haml 3.2.0.alpha.10 → 3.2.0.alpha.13

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of haml might be problematic. Click here for more details.

Files changed (389) hide show
  1. data/.yardopts +19 -7
  2. data/CHANGELOG.md +1224 -0
  3. data/FAQ.md +157 -0
  4. data/README.md +99 -62
  5. data/REFERENCE.md +1404 -0
  6. data/Rakefile +52 -341
  7. data/init.rb +1 -18
  8. data/lib/haml.rb +6 -30
  9. data/lib/haml/buffer.rb +37 -16
  10. data/lib/haml/compiler.rb +52 -13
  11. data/lib/haml/engine.rb +61 -44
  12. data/lib/haml/exec.rb +21 -4
  13. data/lib/haml/filters.rb +136 -166
  14. data/lib/haml/helpers.rb +37 -10
  15. data/lib/haml/helpers/action_view_extensions.rb +2 -1
  16. data/lib/haml/helpers/action_view_mods.rb +67 -181
  17. data/lib/haml/helpers/rails_323_textarea_fix.rb +39 -0
  18. data/lib/haml/helpers/xss_mods.rb +9 -11
  19. data/lib/haml/html.rb +22 -9
  20. data/lib/haml/html/erb.rb +1 -1
  21. data/lib/haml/parser.rb +22 -15
  22. data/lib/haml/railtie.rb +2 -13
  23. data/lib/haml/template.rb +18 -85
  24. data/lib/haml/template/options.rb +1 -1
  25. data/lib/haml/template/plugin.rb +15 -101
  26. data/lib/haml/util.rb +120 -603
  27. data/lib/haml/version.rb +1 -107
  28. data/test/{haml/engine_test.rb → engine_test.rb} +137 -143
  29. data/test/{haml/erb → erb}/_av_partial_1.erb +1 -1
  30. data/test/{haml/erb → erb}/_av_partial_2.erb +1 -1
  31. data/test/{haml/erb → erb}/action_view.erb +1 -1
  32. data/test/{haml/erb → erb}/standard.erb +0 -0
  33. data/test/filters_test.rb +141 -0
  34. data/test/gemfiles/Gemfile.rails-3.0.x +4 -6
  35. data/test/gemfiles/Gemfile.rails-3.1.x +5 -6
  36. data/test/gemfiles/Gemfile.rails-3.2.x +6 -0
  37. data/test/haml-spec/LICENSE +14 -0
  38. data/test/{haml/spec → haml-spec}/README.md +26 -17
  39. data/test/haml-spec/lua_haml_spec.lua +38 -0
  40. data/test/haml-spec/perl_haml_test.pl +81 -0
  41. data/test/haml-spec/ruby_haml_test.rb +23 -0
  42. data/test/{haml/spec → haml-spec}/tests.json +132 -54
  43. data/test/{haml/helper_test.rb → helper_test.rb} +50 -36
  44. data/test/{haml/html2haml → html2haml}/erb_tests.rb +0 -0
  45. data/test/{haml/html2haml_test.rb → html2haml_test.rb} +11 -5
  46. data/test/{haml/markaby → markaby}/standard.mab +0 -0
  47. data/test/{haml/mocks → mocks}/article.rb +0 -0
  48. data/test/{haml/results → results}/content_for_layout.xhtml +0 -0
  49. data/test/{haml/results → results}/eval_suppressed.xhtml +0 -0
  50. data/test/{haml/results → results}/helpers.xhtml +0 -0
  51. data/test/{haml/results → results}/helpful.xhtml +0 -0
  52. data/test/{haml/results → results}/just_stuff.xhtml +0 -0
  53. data/test/{haml/results → results}/list.xhtml +0 -0
  54. data/test/{haml/results → results}/nuke_inner_whitespace.xhtml +0 -0
  55. data/test/{haml/results → results}/nuke_outer_whitespace.xhtml +0 -0
  56. data/test/{haml/results → results}/original_engine.xhtml +0 -0
  57. data/test/{haml/results → results}/partial_layout.xhtml +0 -0
  58. data/test/{haml/results → results}/partials.xhtml +0 -0
  59. data/test/{haml/results → results}/render_layout.xhtml +0 -0
  60. data/test/{haml/results → results}/silent_script.xhtml +1 -1
  61. data/test/{haml/results → results}/standard.xhtml +0 -0
  62. data/test/{haml/results → results}/tag_parsing.xhtml +0 -0
  63. data/test/{haml/results → results}/very_basic.xhtml +0 -0
  64. data/test/{haml/results → results}/whitespace_handling.xhtml +46 -50
  65. data/test/{haml/template_test.rb → template_test.rb} +20 -81
  66. data/test/{haml/templates → templates}/_av_partial_1.haml +1 -1
  67. data/test/{haml/templates → templates}/_av_partial_1_ugly.haml +1 -1
  68. data/test/{haml/templates → templates}/_av_partial_2.haml +1 -1
  69. data/test/{haml/templates → templates}/_av_partial_2_ugly.haml +1 -1
  70. data/test/{haml/templates → templates}/_layout.erb +0 -0
  71. data/test/{haml/templates → templates}/_layout_for_partial.haml +0 -0
  72. data/test/{haml/templates → templates}/_partial.haml +0 -0
  73. data/test/{haml/templates → templates}/_text_area.haml +0 -0
  74. data/test/{haml/templates → templates}/action_view.haml +1 -1
  75. data/test/{haml/templates → templates}/action_view_ugly.haml +1 -1
  76. data/test/{haml/templates → templates}/breakage.haml +0 -0
  77. data/test/{haml/templates → templates}/content_for_layout.haml +0 -0
  78. data/test/{haml/templates → templates}/eval_suppressed.haml +0 -0
  79. data/test/{haml/templates → templates}/helpers.haml +0 -0
  80. data/test/{haml/templates → templates}/helpful.haml +0 -0
  81. data/test/{haml/templates → templates}/just_stuff.haml +0 -0
  82. data/test/{haml/templates → templates}/list.haml +0 -0
  83. data/test/{haml/templates → templates}/nuke_inner_whitespace.haml +0 -0
  84. data/test/{haml/templates → templates}/nuke_outer_whitespace.haml +0 -0
  85. data/test/{haml/templates → templates}/original_engine.haml +0 -0
  86. data/test/templates/partial_layout.haml +3 -0
  87. data/test/{haml/templates → templates}/partialize.haml +0 -0
  88. data/test/{haml/templates → templates}/partials.haml +0 -0
  89. data/test/{haml/templates → templates}/render_layout.haml +0 -0
  90. data/test/{haml/templates → templates}/silent_script.haml +2 -2
  91. data/test/{haml/templates → templates}/standard.haml +0 -0
  92. data/test/{haml/templates → templates}/standard_ugly.haml +0 -0
  93. data/test/{haml/templates → templates}/tag_parsing.haml +0 -0
  94. data/test/{haml/templates → templates}/very_basic.haml +0 -0
  95. data/test/{haml/templates → templates}/whitespace_handling.haml +0 -0
  96. data/test/test_helper.rb +42 -34
  97. data/test/util_test.rb +80 -0
  98. metadata +259 -427
  99. data/CONTRIBUTING +0 -3
  100. data/REVISION +0 -1
  101. data/VERSION +0 -1
  102. data/VERSION_NAME +0 -1
  103. data/extra/update_watch.rb +0 -13
  104. data/lib/haml/root.rb +0 -7
  105. data/lib/haml/shared.rb +0 -78
  106. data/lib/haml/template/patch.rb +0 -58
  107. data/lib/sass.rb +0 -8
  108. data/lib/sass/plugin.rb +0 -10
  109. data/lib/sass/rails2_shim.rb +0 -9
  110. data/lib/sass/rails3_shim.rb +0 -16
  111. data/test/benchmark.rb +0 -91
  112. data/test/gemfiles/Gemfile.rails-2.0.x +0 -8
  113. data/test/gemfiles/Gemfile.rails-2.0.x.lock +0 -38
  114. data/test/gemfiles/Gemfile.rails-2.1.x +0 -8
  115. data/test/gemfiles/Gemfile.rails-2.1.x.lock +0 -38
  116. data/test/gemfiles/Gemfile.rails-2.2.x +0 -8
  117. data/test/gemfiles/Gemfile.rails-2.2.x.lock +0 -38
  118. data/test/gemfiles/Gemfile.rails-2.3.x +0 -8
  119. data/test/gemfiles/Gemfile.rails-2.3.x.lock +0 -40
  120. data/test/gemfiles/Gemfile.rails-3.0.x.lock +0 -85
  121. data/test/gemfiles/Gemfile.rails-3.1.x.lock +0 -98
  122. data/test/gemfiles/Gemfile.rails-xss-2.3.x +0 -9
  123. data/test/gemfiles/Gemfile.rails-xss-2.3.x.lock +0 -42
  124. data/test/haml/results/filters.xhtml +0 -62
  125. data/test/haml/spec/lua_haml_spec.lua +0 -30
  126. data/test/haml/spec/ruby_haml_test.rb +0 -19
  127. data/test/haml/spec_test.rb +0 -44
  128. data/test/haml/templates/filters.haml +0 -66
  129. data/test/haml/templates/partial_layout.haml +0 -10
  130. data/test/haml/util_test.rb +0 -300
  131. data/test/linked_rails.rb +0 -42
  132. data/vendor/sass/CONTRIBUTING +0 -3
  133. data/vendor/sass/MIT-LICENSE +0 -20
  134. data/vendor/sass/README.md +0 -201
  135. data/vendor/sass/Rakefile +0 -339
  136. data/vendor/sass/TODO +0 -39
  137. data/vendor/sass/VERSION +0 -1
  138. data/vendor/sass/VERSION_NAME +0 -1
  139. data/vendor/sass/bin/sass +0 -8
  140. data/vendor/sass/bin/sass-convert +0 -7
  141. data/vendor/sass/bin/scss +0 -8
  142. data/vendor/sass/doc-src/FAQ.md +0 -35
  143. data/vendor/sass/doc-src/INDENTED_SYNTAX.md +0 -210
  144. data/vendor/sass/doc-src/SASS_CHANGELOG.md +0 -2327
  145. data/vendor/sass/doc-src/SASS_REFERENCE.md +0 -1965
  146. data/vendor/sass/doc-src/SCSS_FOR_SASS_USERS.md +0 -155
  147. data/vendor/sass/ext/extconf.rb +0 -10
  148. data/vendor/sass/extra/update_watch.rb +0 -13
  149. data/vendor/sass/init.rb +0 -18
  150. data/vendor/sass/lib/sass.rb +0 -73
  151. data/vendor/sass/lib/sass/cache_stores.rb +0 -15
  152. data/vendor/sass/lib/sass/cache_stores/base.rb +0 -86
  153. data/vendor/sass/lib/sass/cache_stores/chain.rb +0 -33
  154. data/vendor/sass/lib/sass/cache_stores/filesystem.rb +0 -60
  155. data/vendor/sass/lib/sass/cache_stores/memory.rb +0 -47
  156. data/vendor/sass/lib/sass/cache_stores/null.rb +0 -25
  157. data/vendor/sass/lib/sass/callbacks.rb +0 -66
  158. data/vendor/sass/lib/sass/css.rb +0 -295
  159. data/vendor/sass/lib/sass/engine.rb +0 -878
  160. data/vendor/sass/lib/sass/environment.rb +0 -166
  161. data/vendor/sass/lib/sass/error.rb +0 -201
  162. data/vendor/sass/lib/sass/exec.rb +0 -672
  163. data/vendor/sass/lib/sass/importers.rb +0 -22
  164. data/vendor/sass/lib/sass/importers/base.rb +0 -139
  165. data/vendor/sass/lib/sass/importers/filesystem.rb +0 -149
  166. data/vendor/sass/lib/sass/less.rb +0 -382
  167. data/vendor/sass/lib/sass/logger.rb +0 -15
  168. data/vendor/sass/lib/sass/logger/base.rb +0 -32
  169. data/vendor/sass/lib/sass/logger/log_level.rb +0 -49
  170. data/vendor/sass/lib/sass/plugin.rb +0 -132
  171. data/vendor/sass/lib/sass/plugin/compiler.rb +0 -383
  172. data/vendor/sass/lib/sass/plugin/configuration.rb +0 -123
  173. data/vendor/sass/lib/sass/plugin/generic.rb +0 -15
  174. data/vendor/sass/lib/sass/plugin/merb.rb +0 -48
  175. data/vendor/sass/lib/sass/plugin/rack.rb +0 -60
  176. data/vendor/sass/lib/sass/plugin/rails.rb +0 -47
  177. data/vendor/sass/lib/sass/plugin/staleness_checker.rb +0 -173
  178. data/vendor/sass/lib/sass/railtie.rb +0 -9
  179. data/vendor/sass/lib/sass/repl.rb +0 -58
  180. data/vendor/sass/lib/sass/root.rb +0 -7
  181. data/vendor/sass/lib/sass/script.rb +0 -40
  182. data/vendor/sass/lib/sass/script/bool.rb +0 -18
  183. data/vendor/sass/lib/sass/script/color.rb +0 -480
  184. data/vendor/sass/lib/sass/script/css_lexer.rb +0 -29
  185. data/vendor/sass/lib/sass/script/css_parser.rb +0 -31
  186. data/vendor/sass/lib/sass/script/funcall.rb +0 -175
  187. data/vendor/sass/lib/sass/script/functions.rb +0 -1386
  188. data/vendor/sass/lib/sass/script/interpolation.rb +0 -79
  189. data/vendor/sass/lib/sass/script/lexer.rb +0 -339
  190. data/vendor/sass/lib/sass/script/list.rb +0 -83
  191. data/vendor/sass/lib/sass/script/literal.rb +0 -250
  192. data/vendor/sass/lib/sass/script/node.rb +0 -99
  193. data/vendor/sass/lib/sass/script/number.rb +0 -452
  194. data/vendor/sass/lib/sass/script/operation.rb +0 -99
  195. data/vendor/sass/lib/sass/script/parser.rb +0 -474
  196. data/vendor/sass/lib/sass/script/string.rb +0 -51
  197. data/vendor/sass/lib/sass/script/string_interpolation.rb +0 -103
  198. data/vendor/sass/lib/sass/script/unary_operation.rb +0 -64
  199. data/vendor/sass/lib/sass/script/variable.rb +0 -59
  200. data/vendor/sass/lib/sass/scss.rb +0 -17
  201. data/vendor/sass/lib/sass/scss/css_parser.rb +0 -46
  202. data/vendor/sass/lib/sass/scss/parser.rb +0 -960
  203. data/vendor/sass/lib/sass/scss/rx.rb +0 -128
  204. data/vendor/sass/lib/sass/scss/sass_parser.rb +0 -11
  205. data/vendor/sass/lib/sass/scss/script_lexer.rb +0 -15
  206. data/vendor/sass/lib/sass/scss/script_parser.rb +0 -25
  207. data/vendor/sass/lib/sass/scss/static_parser.rb +0 -40
  208. data/vendor/sass/lib/sass/selector.rb +0 -361
  209. data/vendor/sass/lib/sass/selector/abstract_sequence.rb +0 -62
  210. data/vendor/sass/lib/sass/selector/comma_sequence.rb +0 -81
  211. data/vendor/sass/lib/sass/selector/sequence.rb +0 -233
  212. data/vendor/sass/lib/sass/selector/simple.rb +0 -113
  213. data/vendor/sass/lib/sass/selector/simple_sequence.rb +0 -134
  214. data/vendor/sass/lib/sass/shared.rb +0 -78
  215. data/vendor/sass/lib/sass/tree/charset_node.rb +0 -22
  216. data/vendor/sass/lib/sass/tree/comment_node.rb +0 -90
  217. data/vendor/sass/lib/sass/tree/debug_node.rb +0 -18
  218. data/vendor/sass/lib/sass/tree/directive_node.rb +0 -23
  219. data/vendor/sass/lib/sass/tree/each_node.rb +0 -24
  220. data/vendor/sass/lib/sass/tree/extend_node.rb +0 -29
  221. data/vendor/sass/lib/sass/tree/for_node.rb +0 -36
  222. data/vendor/sass/lib/sass/tree/function_node.rb +0 -27
  223. data/vendor/sass/lib/sass/tree/if_node.rb +0 -52
  224. data/vendor/sass/lib/sass/tree/import_node.rb +0 -68
  225. data/vendor/sass/lib/sass/tree/media_node.rb +0 -32
  226. data/vendor/sass/lib/sass/tree/mixin_def_node.rb +0 -27
  227. data/vendor/sass/lib/sass/tree/mixin_node.rb +0 -32
  228. data/vendor/sass/lib/sass/tree/node.rb +0 -201
  229. data/vendor/sass/lib/sass/tree/prop_node.rb +0 -148
  230. data/vendor/sass/lib/sass/tree/return_node.rb +0 -18
  231. data/vendor/sass/lib/sass/tree/root_node.rb +0 -28
  232. data/vendor/sass/lib/sass/tree/rule_node.rb +0 -136
  233. data/vendor/sass/lib/sass/tree/variable_node.rb +0 -30
  234. data/vendor/sass/lib/sass/tree/visitors/base.rb +0 -75
  235. data/vendor/sass/lib/sass/tree/visitors/check_nesting.rb +0 -133
  236. data/vendor/sass/lib/sass/tree/visitors/convert.rb +0 -260
  237. data/vendor/sass/lib/sass/tree/visitors/cssize.rb +0 -175
  238. data/vendor/sass/lib/sass/tree/visitors/deep_copy.rb +0 -87
  239. data/vendor/sass/lib/sass/tree/visitors/perform.rb +0 -332
  240. data/vendor/sass/lib/sass/tree/visitors/set_options.rb +0 -97
  241. data/vendor/sass/lib/sass/tree/visitors/to_css.rb +0 -210
  242. data/vendor/sass/lib/sass/tree/warn_node.rb +0 -18
  243. data/vendor/sass/lib/sass/tree/while_node.rb +0 -18
  244. data/vendor/sass/lib/sass/util.rb +0 -721
  245. data/vendor/sass/lib/sass/util/subset_map.rb +0 -101
  246. data/vendor/sass/lib/sass/version.rb +0 -112
  247. data/vendor/sass/rails/init.rb +0 -1
  248. data/vendor/sass/sass.gemspec +0 -33
  249. data/vendor/sass/test/Gemfile +0 -4
  250. data/vendor/sass/test/Gemfile.lock +0 -19
  251. data/vendor/sass/test/sass/cache_test.rb +0 -89
  252. data/vendor/sass/test/sass/callbacks_test.rb +0 -61
  253. data/vendor/sass/test/sass/conversion_test.rb +0 -1199
  254. data/vendor/sass/test/sass/css2sass_test.rb +0 -373
  255. data/vendor/sass/test/sass/data/hsl-rgb.txt +0 -319
  256. data/vendor/sass/test/sass/engine_test.rb +0 -2567
  257. data/vendor/sass/test/sass/extend_test.rb +0 -1348
  258. data/vendor/sass/test/sass/fixtures/test_staleness_check_across_importers.css +0 -1
  259. data/vendor/sass/test/sass/fixtures/test_staleness_check_across_importers.scss +0 -1
  260. data/vendor/sass/test/sass/functions_test.rb +0 -1038
  261. data/vendor/sass/test/sass/importer_test.rb +0 -192
  262. data/vendor/sass/test/sass/less_conversion_test.rb +0 -653
  263. data/vendor/sass/test/sass/logger_test.rb +0 -58
  264. data/vendor/sass/test/sass/mock_importer.rb +0 -49
  265. data/vendor/sass/test/sass/more_results/more1.css +0 -9
  266. data/vendor/sass/test/sass/more_results/more1_with_line_comments.css +0 -26
  267. data/vendor/sass/test/sass/more_results/more_import.css +0 -29
  268. data/vendor/sass/test/sass/more_templates/_more_partial.sass +0 -2
  269. data/vendor/sass/test/sass/more_templates/more1.sass +0 -23
  270. data/vendor/sass/test/sass/more_templates/more_import.sass +0 -11
  271. data/vendor/sass/test/sass/plugin_test.rb +0 -472
  272. data/vendor/sass/test/sass/results/alt.css +0 -4
  273. data/vendor/sass/test/sass/results/basic.css +0 -9
  274. data/vendor/sass/test/sass/results/compact.css +0 -5
  275. data/vendor/sass/test/sass/results/complex.css +0 -86
  276. data/vendor/sass/test/sass/results/compressed.css +0 -1
  277. data/vendor/sass/test/sass/results/expanded.css +0 -19
  278. data/vendor/sass/test/sass/results/if.css +0 -3
  279. data/vendor/sass/test/sass/results/import.css +0 -31
  280. data/vendor/sass/test/sass/results/import_charset.css +0 -4
  281. data/vendor/sass/test/sass/results/import_charset_1_8.css +0 -4
  282. data/vendor/sass/test/sass/results/import_charset_ibm866.css +0 -4
  283. data/vendor/sass/test/sass/results/line_numbers.css +0 -49
  284. data/vendor/sass/test/sass/results/mixins.css +0 -95
  285. data/vendor/sass/test/sass/results/multiline.css +0 -24
  286. data/vendor/sass/test/sass/results/nested.css +0 -22
  287. data/vendor/sass/test/sass/results/options.css +0 -1
  288. data/vendor/sass/test/sass/results/parent_ref.css +0 -13
  289. data/vendor/sass/test/sass/results/script.css +0 -16
  290. data/vendor/sass/test/sass/results/scss_import.css +0 -31
  291. data/vendor/sass/test/sass/results/scss_importee.css +0 -2
  292. data/vendor/sass/test/sass/results/subdir/nested_subdir/nested_subdir.css +0 -1
  293. data/vendor/sass/test/sass/results/subdir/subdir.css +0 -3
  294. data/vendor/sass/test/sass/results/units.css +0 -11
  295. data/vendor/sass/test/sass/results/warn.css +0 -0
  296. data/vendor/sass/test/sass/results/warn_imported.css +0 -0
  297. data/vendor/sass/test/sass/script_conversion_test.rb +0 -285
  298. data/vendor/sass/test/sass/script_test.rb +0 -514
  299. data/vendor/sass/test/sass/scss/css_test.rb +0 -922
  300. data/vendor/sass/test/sass/scss/rx_test.rb +0 -156
  301. data/vendor/sass/test/sass/scss/scss_test.rb +0 -1273
  302. data/vendor/sass/test/sass/scss/test_helper.rb +0 -37
  303. data/vendor/sass/test/sass/templates/_imported_charset_ibm866.sass +0 -4
  304. data/vendor/sass/test/sass/templates/_imported_charset_utf8.sass +0 -4
  305. data/vendor/sass/test/sass/templates/_partial.sass +0 -2
  306. data/vendor/sass/test/sass/templates/alt.sass +0 -16
  307. data/vendor/sass/test/sass/templates/basic.sass +0 -23
  308. data/vendor/sass/test/sass/templates/bork1.sass +0 -2
  309. data/vendor/sass/test/sass/templates/bork2.sass +0 -2
  310. data/vendor/sass/test/sass/templates/bork3.sass +0 -2
  311. data/vendor/sass/test/sass/templates/bork4.sass +0 -2
  312. data/vendor/sass/test/sass/templates/bork5.sass +0 -3
  313. data/vendor/sass/test/sass/templates/compact.sass +0 -17
  314. data/vendor/sass/test/sass/templates/complex.sass +0 -305
  315. data/vendor/sass/test/sass/templates/compressed.sass +0 -15
  316. data/vendor/sass/test/sass/templates/expanded.sass +0 -17
  317. data/vendor/sass/test/sass/templates/if.sass +0 -11
  318. data/vendor/sass/test/sass/templates/import.sass +0 -12
  319. data/vendor/sass/test/sass/templates/import_charset.sass +0 -7
  320. data/vendor/sass/test/sass/templates/import_charset_1_8.sass +0 -4
  321. data/vendor/sass/test/sass/templates/import_charset_ibm866.sass +0 -9
  322. data/vendor/sass/test/sass/templates/importee.less +0 -2
  323. data/vendor/sass/test/sass/templates/importee.sass +0 -19
  324. data/vendor/sass/test/sass/templates/line_numbers.sass +0 -13
  325. data/vendor/sass/test/sass/templates/mixin_bork.sass +0 -5
  326. data/vendor/sass/test/sass/templates/mixins.sass +0 -76
  327. data/vendor/sass/test/sass/templates/multiline.sass +0 -20
  328. data/vendor/sass/test/sass/templates/nested.sass +0 -25
  329. data/vendor/sass/test/sass/templates/nested_bork1.sass +0 -2
  330. data/vendor/sass/test/sass/templates/nested_bork2.sass +0 -2
  331. data/vendor/sass/test/sass/templates/nested_bork3.sass +0 -2
  332. data/vendor/sass/test/sass/templates/nested_bork4.sass +0 -2
  333. data/vendor/sass/test/sass/templates/nested_bork5.sass +0 -2
  334. data/vendor/sass/test/sass/templates/nested_import.sass +0 -2
  335. data/vendor/sass/test/sass/templates/nested_mixin_bork.sass +0 -6
  336. data/vendor/sass/test/sass/templates/options.sass +0 -2
  337. data/vendor/sass/test/sass/templates/parent_ref.sass +0 -25
  338. data/vendor/sass/test/sass/templates/script.sass +0 -101
  339. data/vendor/sass/test/sass/templates/scss_import.scss +0 -11
  340. data/vendor/sass/test/sass/templates/scss_importee.scss +0 -1
  341. data/vendor/sass/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +0 -2
  342. data/vendor/sass/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +0 -3
  343. data/vendor/sass/test/sass/templates/subdir/subdir.sass +0 -6
  344. data/vendor/sass/test/sass/templates/units.sass +0 -11
  345. data/vendor/sass/test/sass/templates/warn.sass +0 -3
  346. data/vendor/sass/test/sass/templates/warn_imported.sass +0 -4
  347. data/vendor/sass/test/sass/test_helper.rb +0 -8
  348. data/vendor/sass/test/sass/util/subset_map_test.rb +0 -91
  349. data/vendor/sass/test/sass/util_test.rb +0 -266
  350. data/vendor/sass/test/test_helper.rb +0 -69
  351. data/vendor/sass/vendor/fssm/Gemfile +0 -3
  352. data/vendor/sass/vendor/fssm/LICENSE +0 -20
  353. data/vendor/sass/vendor/fssm/README.markdown +0 -83
  354. data/vendor/sass/vendor/fssm/Rakefile +0 -11
  355. data/vendor/sass/vendor/fssm/example.rb +0 -12
  356. data/vendor/sass/vendor/fssm/fssm.gemspec +0 -24
  357. data/vendor/sass/vendor/fssm/lib/fssm.rb +0 -37
  358. data/vendor/sass/vendor/fssm/lib/fssm/backends/fsevents.rb +0 -36
  359. data/vendor/sass/vendor/fssm/lib/fssm/backends/inotify.rb +0 -26
  360. data/vendor/sass/vendor/fssm/lib/fssm/backends/polling.rb +0 -25
  361. data/vendor/sass/vendor/fssm/lib/fssm/backends/rbfsevent.rb +0 -42
  362. data/vendor/sass/vendor/fssm/lib/fssm/backends/rubycocoa/fsevents.rb +0 -131
  363. data/vendor/sass/vendor/fssm/lib/fssm/monitor.rb +0 -36
  364. data/vendor/sass/vendor/fssm/lib/fssm/path.rb +0 -94
  365. data/vendor/sass/vendor/fssm/lib/fssm/pathname.rb +0 -36
  366. data/vendor/sass/vendor/fssm/lib/fssm/state/directory.rb +0 -75
  367. data/vendor/sass/vendor/fssm/lib/fssm/state/file.rb +0 -24
  368. data/vendor/sass/vendor/fssm/lib/fssm/support.rb +0 -92
  369. data/vendor/sass/vendor/fssm/lib/fssm/tree.rb +0 -176
  370. data/vendor/sass/vendor/fssm/lib/fssm/version.rb +0 -3
  371. data/vendor/sass/vendor/fssm/profile/prof-cache.rb +0 -40
  372. data/vendor/sass/vendor/fssm/profile/prof-fssm-pathname.html +0 -1231
  373. data/vendor/sass/vendor/fssm/profile/prof-pathname-rubinius.rb +0 -35
  374. data/vendor/sass/vendor/fssm/profile/prof-pathname.rb +0 -68
  375. data/vendor/sass/vendor/fssm/profile/prof-plain-pathname.html +0 -988
  376. data/vendor/sass/vendor/fssm/profile/prof.html +0 -2379
  377. data/vendor/sass/vendor/fssm/spec/count_down_latch.rb +0 -151
  378. data/vendor/sass/vendor/fssm/spec/monitor_spec.rb +0 -202
  379. data/vendor/sass/vendor/fssm/spec/path_spec.rb +0 -96
  380. data/vendor/sass/vendor/fssm/spec/root/duck/quack.txt +0 -0
  381. data/vendor/sass/vendor/fssm/spec/root/file.css +0 -0
  382. data/vendor/sass/vendor/fssm/spec/root/file.rb +0 -0
  383. data/vendor/sass/vendor/fssm/spec/root/file.yml +0 -0
  384. data/vendor/sass/vendor/fssm/spec/root/moo/cow.txt +0 -0
  385. data/vendor/sass/vendor/fssm/spec/spec_helper.rb +0 -14
  386. data/vendor/sass/yard/callbacks.rb +0 -29
  387. data/vendor/sass/yard/default/fulldoc/html/css/common.sass +0 -26
  388. data/vendor/sass/yard/default/layout/html/footer.erb +0 -12
  389. data/vendor/sass/yard/inherited_hash.rb +0 -41
@@ -1,47 +0,0 @@
1
- module Sass
2
- module CacheStores
3
- # A backend for the Sass cache using in-process memory.
4
- class Memory < Base
5
- # Since the {Memory} store is stored in the Sass tree's options hash,
6
- # when the options get serialized as part of serializing the tree,
7
- # you get crazy exponential growth in the size of the cached objects
8
- # unless you don't dump the cache.
9
- #
10
- # @private
11
- def _dump(depth)
12
- ""
13
- end
14
-
15
- # If we deserialize this class, just make a new empty one.
16
- #
17
- # @private
18
- def self._load(repr)
19
- Memory.new
20
- end
21
-
22
- # Create a new, empty cache store.
23
- def initialize
24
- @contents = {}
25
- end
26
-
27
- # @see Base#retrieve
28
- def retrieve(key, sha)
29
- if @contents.has_key?(key)
30
- return unless @contents[key][:sha] == sha
31
- obj = @contents[key][:obj]
32
- obj.respond_to?(:deep_copy) ? obj.deep_copy : obj.dup
33
- end
34
- end
35
-
36
- # @see Base#store
37
- def store(key, sha, obj)
38
- @contents[key] = {:sha => sha, :obj => obj}
39
- end
40
-
41
- # Destructively clear the cache.
42
- def reset!
43
- @contents = {}
44
- end
45
- end
46
- end
47
- end
@@ -1,25 +0,0 @@
1
- module Sass
2
- module CacheStores
3
- # Doesn't store anything, but records what things it should have stored.
4
- # This doesn't currently have any use except for testing and debugging.
5
- #
6
- # @private
7
- class Null < Base
8
- def initialize
9
- @keys = {}
10
- end
11
-
12
- def _retrieve(key, version, sha)
13
- nil
14
- end
15
-
16
- def _store(key, version, sha, contents)
17
- @keys[key] = true
18
- end
19
-
20
- def was_set?(key)
21
- @keys[key]
22
- end
23
- end
24
- end
25
- end
@@ -1,66 +0,0 @@
1
- module Sass
2
- # A lightweight infrastructure for defining and running callbacks.
3
- # Callbacks are defined using \{#define\_callback\} at the class level,
4
- # and called using `run_#{name}` at the instance level.
5
- #
6
- # Clients can add callbacks by calling the generated `on_#{name}` method,
7
- # and passing in a block that's run when the callback is activated.
8
- #
9
- # @example Define a callback
10
- # class Munger
11
- # extend Sass::Callbacks
12
- # define_callback :string_munged
13
- #
14
- # def munge(str)
15
- # res = str.gsub(/[a-z]/, '\1\1')
16
- # run_string_munged str, res
17
- # res
18
- # end
19
- # end
20
- #
21
- # @example Use a callback
22
- # m = Munger.new
23
- # m.on_string_munged {|str, res| puts "#{str} was munged into #{res}!"}
24
- # m.munge "bar" #=> bar was munged into bbaarr!
25
- module Callbacks
26
- # Automatically includes {InstanceMethods}
27
- # when something extends this module.
28
- #
29
- # @param base [Module]
30
- def self.extended(base)
31
- base.send(:include, InstanceMethods)
32
- end
33
- protected
34
-
35
- module InstanceMethods
36
- # Removes all callbacks registered against this object.
37
- def clear_callbacks!
38
- @_sass_callbacks = {}
39
- end
40
- end
41
-
42
- # Define a callback with the given name.
43
- # This will define an `on_#{name}` method
44
- # that registers a block,
45
- # and a `run_#{name}` method that runs that block
46
- # (optionall with some arguments).
47
- #
48
- # @param name [Symbol] The name of the callback
49
- # @return [void]
50
- def define_callback(name)
51
- class_eval <<RUBY
52
- def on_#{name}(&block)
53
- @_sass_callbacks ||= {}
54
- (@_sass_callbacks[#{name.inspect}] ||= []) << block
55
- end
56
-
57
- def run_#{name}(*args)
58
- return unless @_sass_callbacks
59
- return unless @_sass_callbacks[#{name.inspect}]
60
- @_sass_callbacks[#{name.inspect}].each {|c| c[*args]}
61
- end
62
- private :run_#{name}
63
- RUBY
64
- end
65
- end
66
- end
@@ -1,295 +0,0 @@
1
- require File.dirname(__FILE__) + '/../sass'
2
- require 'sass/tree/node'
3
- require 'sass/scss/css_parser'
4
- require 'strscan'
5
-
6
- module Sass
7
- # This class converts CSS documents into Sass or SCSS templates.
8
- # It works by parsing the CSS document into a {Sass::Tree} structure,
9
- # and then applying various transformations to the structure
10
- # to produce more concise and idiomatic Sass/SCSS.
11
- #
12
- # Example usage:
13
- #
14
- # Sass::CSS.new("p { color: blue }").render(:sass) #=> "p\n color: blue"
15
- # Sass::CSS.new("p { color: blue }").render(:scss) #=> "p {\n color: blue; }"
16
- class CSS
17
- # @param template [String] The CSS stylesheet.
18
- # This stylesheet can be encoded using any encoding
19
- # that can be converted to Unicode.
20
- # If the stylesheet contains an `@charset` declaration,
21
- # that overrides the Ruby encoding
22
- # (see {file:SASS_REFERENCE.md#encodings the encoding documentation})
23
- # @option options :old [Boolean] (false)
24
- # Whether or not to output old property syntax
25
- # (`:color blue` as opposed to `color: blue`).
26
- # This is only meaningful when generating Sass code,
27
- # rather than SCSS.
28
- def initialize(template, options = {})
29
- if template.is_a? IO
30
- template = template.read
31
- end
32
-
33
- @options = options.dup
34
- # Backwards compatibility
35
- @options[:old] = true if @options[:alternate] == false
36
- @template = template
37
- end
38
-
39
- # Converts the CSS template into Sass or SCSS code.
40
- #
41
- # @param fmt [Symbol] `:sass` or `:scss`, designating the format to return.
42
- # @return [String] The resulting Sass or SCSS code
43
- # @raise [Sass::SyntaxError] if there's an error parsing the CSS template
44
- def render(fmt = :sass)
45
- check_encoding!
46
- build_tree.send("to_#{fmt}", @options).strip + "\n"
47
- rescue Sass::SyntaxError => err
48
- err.modify_backtrace(:filename => @options[:filename] || '(css)')
49
- raise err
50
- end
51
-
52
- # Returns the original encoding of the document,
53
- # or `nil` under Ruby 1.8.
54
- #
55
- # @return [Encoding, nil]
56
- # @raise [Encoding::UndefinedConversionError] if the source encoding
57
- # cannot be converted to UTF-8
58
- # @raise [ArgumentError] if the document uses an unknown encoding with `@charset`
59
- def source_encoding
60
- check_encoding!
61
- @original_encoding
62
- end
63
-
64
- private
65
-
66
- def check_encoding!
67
- return if @checked_encoding
68
- @checked_encoding = true
69
- @template, @original_encoding = Sass::Util.check_sass_encoding(@template) do |msg, line|
70
- raise Sass::SyntaxError.new(msg, :line => line)
71
- end
72
- end
73
-
74
- # Parses the CSS template and applies various transformations
75
- #
76
- # @return [Tree::Node] The root node of the parsed tree
77
- def build_tree
78
- root = Sass::SCSS::CssParser.new(@template, @options[:filename]).parse
79
- expand_commas root
80
- parent_ref_rules root
81
- remove_parent_refs root
82
- flatten_rules root
83
- fold_commas root
84
- root
85
- end
86
-
87
- # Transform
88
- #
89
- # foo, bar, baz
90
- # color: blue
91
- #
92
- # into
93
- #
94
- # foo
95
- # color: blue
96
- # bar
97
- # color: blue
98
- # baz
99
- # color: blue
100
- #
101
- # @param root [Tree::Node] The parent node
102
- def expand_commas(root)
103
- root.children.map! do |child|
104
- unless child.is_a?(Tree::RuleNode) && child.rule.first.include?(',')
105
- expand_commas(child) if child.is_a?(Tree::DirectiveNode)
106
- next child
107
- end
108
- child.rule.first.split(',').map do |rule|
109
- next if rule.strip.empty?
110
- node = Tree::RuleNode.new([rule.strip])
111
- node.children = child.children
112
- node
113
- end
114
- end
115
- root.children.flatten!
116
- end
117
-
118
- # Make rules use parent refs so that
119
- #
120
- # foo
121
- # color: green
122
- # foo.bar
123
- # color: blue
124
- #
125
- # becomes
126
- #
127
- # foo
128
- # color: green
129
- # &.bar
130
- # color: blue
131
- #
132
- # This has the side effect of nesting rules,
133
- # so that
134
- #
135
- # foo
136
- # color: green
137
- # foo bar
138
- # color: red
139
- # foo baz
140
- # color: blue
141
- #
142
- # becomes
143
- #
144
- # foo
145
- # color: green
146
- # & bar
147
- # color: red
148
- # & baz
149
- # color: blue
150
- #
151
- # @param root [Tree::Node] The parent node
152
- def parent_ref_rules(root)
153
- current_rule = nil
154
- root.children.map! do |child|
155
- unless child.is_a?(Tree::RuleNode)
156
- parent_ref_rules(child) if child.is_a?(Tree::DirectiveNode)
157
- next child
158
- end
159
-
160
- first, rest = child.rule.first.scan(/\A(&?(?: .|[^ ])[^.#: \[]*)([.#: \[].*)?\Z/m).first
161
-
162
- if current_rule.nil? || current_rule.rule.first != first
163
- current_rule = Tree::RuleNode.new([first])
164
- end
165
-
166
- if rest
167
- child.rule = ["&" + rest]
168
- current_rule << child
169
- else
170
- current_rule.children += child.children
171
- end
172
-
173
- current_rule
174
- end
175
- root.children.compact!
176
- root.children.uniq!
177
-
178
- root.children.each { |v| parent_ref_rules(v) }
179
- end
180
-
181
- # Remove useless parent refs so that
182
- #
183
- # foo
184
- # & bar
185
- # color: blue
186
- #
187
- # becomes
188
- #
189
- # foo
190
- # bar
191
- # color: blue
192
- #
193
- # @param root [Tree::Node] The parent node
194
- def remove_parent_refs(root)
195
- root.children.each do |child|
196
- case child
197
- when Tree::RuleNode
198
- child.rule.first.gsub! /^& +/, ''
199
- remove_parent_refs child
200
- when Tree::DirectiveNode
201
- remove_parent_refs child
202
- end
203
- end
204
- end
205
-
206
- # Flatten rules so that
207
- #
208
- # foo
209
- # bar
210
- # color: red
211
- #
212
- # becomes
213
- #
214
- # foo bar
215
- # color: red
216
- #
217
- # and
218
- #
219
- # foo
220
- # &.bar
221
- # color: blue
222
- #
223
- # becomes
224
- #
225
- # foo.bar
226
- # color: blue
227
- #
228
- # @param root [Tree::Node] The parent node
229
- def flatten_rules(root)
230
- root.children.each do |child|
231
- case child
232
- when Tree::RuleNode
233
- flatten_rule(child)
234
- when Tree::DirectiveNode
235
- flatten_rules(child)
236
- end
237
- end
238
- end
239
-
240
- # Flattens a single rule
241
- #
242
- # @param rule [Tree::RuleNode] The candidate for flattening
243
- # @see #flatten_rules
244
- def flatten_rule(rule)
245
- while rule.children.size == 1 && rule.children.first.is_a?(Tree::RuleNode)
246
- child = rule.children.first
247
-
248
- if child.rule.first[0] == ?&
249
- rule.rule = [child.rule.first.gsub(/^&/, rule.rule.first)]
250
- else
251
- rule.rule = ["#{rule.rule.first} #{child.rule.first}"]
252
- end
253
-
254
- rule.children = child.children
255
- end
256
-
257
- flatten_rules(rule)
258
- end
259
-
260
- # Transform
261
- #
262
- # foo
263
- # bar
264
- # color: blue
265
- # baz
266
- # color: blue
267
- #
268
- # into
269
- #
270
- # foo
271
- # bar, baz
272
- # color: blue
273
- #
274
- # @param rule [Tree::RuleNode] The candidate for flattening
275
- def fold_commas(root)
276
- prev_rule = nil
277
- root.children.map! do |child|
278
- unless child.is_a?(Tree::RuleNode)
279
- fold_commas(child) if child.is_a?(Tree::DirectiveNode)
280
- next child
281
- end
282
-
283
- if prev_rule && prev_rule.children == child.children
284
- prev_rule.rule.first << ", #{child.rule.first}"
285
- next nil
286
- end
287
-
288
- fold_commas(child)
289
- prev_rule = child
290
- child
291
- end
292
- root.children.compact!
293
- end
294
- end
295
- end
@@ -1,878 +0,0 @@
1
- require 'strscan'
2
- require 'set'
3
- require 'digest/sha1'
4
- require 'sass/cache_stores'
5
- require 'sass/tree/node'
6
- require 'sass/tree/root_node'
7
- require 'sass/tree/rule_node'
8
- require 'sass/tree/comment_node'
9
- require 'sass/tree/prop_node'
10
- require 'sass/tree/directive_node'
11
- require 'sass/tree/media_node'
12
- require 'sass/tree/variable_node'
13
- require 'sass/tree/mixin_def_node'
14
- require 'sass/tree/mixin_node'
15
- require 'sass/tree/function_node'
16
- require 'sass/tree/return_node'
17
- require 'sass/tree/extend_node'
18
- require 'sass/tree/if_node'
19
- require 'sass/tree/while_node'
20
- require 'sass/tree/for_node'
21
- require 'sass/tree/each_node'
22
- require 'sass/tree/debug_node'
23
- require 'sass/tree/warn_node'
24
- require 'sass/tree/import_node'
25
- require 'sass/tree/charset_node'
26
- require 'sass/tree/visitors/base'
27
- require 'sass/tree/visitors/perform'
28
- require 'sass/tree/visitors/cssize'
29
- require 'sass/tree/visitors/convert'
30
- require 'sass/tree/visitors/to_css'
31
- require 'sass/tree/visitors/deep_copy'
32
- require 'sass/tree/visitors/set_options'
33
- require 'sass/tree/visitors/check_nesting'
34
- require 'sass/selector'
35
- require 'sass/environment'
36
- require 'sass/script'
37
- require 'sass/scss'
38
- require 'sass/error'
39
- require 'sass/importers'
40
- require 'sass/shared'
41
-
42
- module Sass
43
-
44
- # A Sass mixin or function.
45
- #
46
- # `name`: `String`
47
- # : The name of the mixin/function.
48
- #
49
- # `args`: `Array<(String, Script::Node)>`
50
- # : The arguments for the mixin/function.
51
- # Each element is a tuple containing the name of the argument
52
- # and the parse tree for the default value of the argument.
53
- #
54
- # `environment`: {Sass::Environment}
55
- # : The environment in which the mixin/function was defined.
56
- # This is captured so that the mixin/function can have access
57
- # to local variables defined in its scope.
58
- #
59
- # `tree`: `Array<Tree::Node>`
60
- # : The parse tree for the mixin/function.
61
- Callable = Struct.new(:name, :args, :environment, :tree)
62
-
63
- # This class handles the parsing and compilation of the Sass template.
64
- # Example usage:
65
- #
66
- # template = File.load('stylesheets/sassy.sass')
67
- # sass_engine = Sass::Engine.new(template)
68
- # output = sass_engine.render
69
- # puts output
70
- class Engine
71
- include Sass::Util
72
-
73
- # A line of Sass code.
74
- #
75
- # `text`: `String`
76
- # : The text in the line, without any whitespace at the beginning or end.
77
- #
78
- # `tabs`: `Fixnum`
79
- # : The level of indentation of the line.
80
- #
81
- # `index`: `Fixnum`
82
- # : The line number in the original document.
83
- #
84
- # `offset`: `Fixnum`
85
- # : The number of bytes in on the line that the text begins.
86
- # This ends up being the number of bytes of leading whitespace.
87
- #
88
- # `filename`: `String`
89
- # : The name of the file in which this line appeared.
90
- #
91
- # `children`: `Array<Line>`
92
- # : The lines nested below this one.
93
- #
94
- # `comment_tab_str`: `String?`
95
- # : The prefix indentation for this comment, if it is a comment.
96
- class Line < Struct.new(:text, :tabs, :index, :offset, :filename, :children, :comment_tab_str)
97
- def comment?
98
- text[0] == COMMENT_CHAR && (text[1] == SASS_COMMENT_CHAR || text[1] == CSS_COMMENT_CHAR)
99
- end
100
- end
101
-
102
- # The character that begins a CSS property.
103
- PROPERTY_CHAR = ?:
104
-
105
- # The character that designates the beginning of a comment,
106
- # either Sass or CSS.
107
- COMMENT_CHAR = ?/
108
-
109
- # The character that follows the general COMMENT_CHAR and designates a Sass comment,
110
- # which is not output as a CSS comment.
111
- SASS_COMMENT_CHAR = ?/
112
-
113
- # The character that indicates that a comment allows interpolation
114
- # and should be preserved even in `:compressed` mode.
115
- SASS_LOUD_COMMENT_CHAR = ?!
116
-
117
- # The character that follows the general COMMENT_CHAR and designates a CSS comment,
118
- # which is embedded in the CSS document.
119
- CSS_COMMENT_CHAR = ?*
120
-
121
- # The character used to denote a compiler directive.
122
- DIRECTIVE_CHAR = ?@
123
-
124
- # Designates a non-parsed rule.
125
- ESCAPE_CHAR = ?\\
126
-
127
- # Designates block as mixin definition rather than CSS rules to output
128
- MIXIN_DEFINITION_CHAR = ?=
129
-
130
- # Includes named mixin declared using MIXIN_DEFINITION_CHAR
131
- MIXIN_INCLUDE_CHAR = ?+
132
-
133
- # The regex that matches and extracts data from
134
- # properties of the form `:name prop`.
135
- PROPERTY_OLD = /^:([^\s=:"]+)\s*(?:\s+|$)(.*)/
136
-
137
- # The default options for Sass::Engine.
138
- # @api public
139
- DEFAULT_OPTIONS = {
140
- :style => :nested,
141
- :load_paths => ['.'],
142
- :cache => true,
143
- :cache_location => './.sass-cache',
144
- :syntax => :sass,
145
- :filesystem_importer => Sass::Importers::Filesystem
146
- }.freeze
147
-
148
- # Converts a Sass options hash into a standard form, filling in
149
- # default values and resolving aliases.
150
- #
151
- # @param options [{Symbol => Object}] The options hash;
152
- # see {file:SASS_REFERENCE.md#sass_options the Sass options documentation}
153
- # @return [{Symbol => Object}] The normalized options hash.
154
- # @private
155
- def self.normalize_options(options)
156
- options = DEFAULT_OPTIONS.merge(options.reject {|k, v| v.nil?})
157
-
158
- # If the `:filename` option is passed in without an importer,
159
- # assume it's using the default filesystem importer.
160
- options[:importer] ||= options[:filesystem_importer].new(".") if options[:filename]
161
-
162
- # Tracks the original filename of the top-level Sass file
163
- options[:original_filename] ||= options[:filename]
164
-
165
- options[:cache_store] ||= Sass::CacheStores::Chain.new(
166
- Sass::CacheStores::Memory.new, Sass::CacheStores::Filesystem.new(options[:cache_location]))
167
- # Support both, because the docs said one and the other actually worked
168
- # for quite a long time.
169
- options[:line_comments] ||= options[:line_numbers]
170
-
171
- options[:load_paths] = options[:load_paths].map do |p|
172
- next p unless p.is_a?(String) || (defined?(Pathname) && p.is_a?(Pathname))
173
- options[:filesystem_importer].new(p.to_s)
174
- end
175
-
176
- # Backwards compatibility
177
- options[:property_syntax] ||= options[:attribute_syntax]
178
- case options[:property_syntax]
179
- when :alternate; options[:property_syntax] = :new
180
- when :normal; options[:property_syntax] = :old
181
- end
182
-
183
- options
184
- end
185
-
186
- # Returns the {Sass::Engine} for the given file.
187
- # This is preferable to Sass::Engine.new when reading from a file
188
- # because it properly sets up the Engine's metadata,
189
- # enables parse-tree caching,
190
- # and infers the syntax from the filename.
191
- #
192
- # @param filename [String] The path to the Sass or SCSS file
193
- # @param options [{Symbol => Object}] The options hash;
194
- # See {file:SASS_REFERENCE.md#sass_options the Sass options documentation}.
195
- # @return [Sass::Engine] The Engine for the given Sass or SCSS file.
196
- # @raise [Sass::SyntaxError] if there's an error in the document.
197
- def self.for_file(filename, options)
198
- had_syntax = options[:syntax]
199
-
200
- if had_syntax
201
- # Use what was explicitly specificed
202
- elsif filename =~ /\.scss$/
203
- options.merge!(:syntax => :scss)
204
- elsif filename =~ /\.sass$/
205
- options.merge!(:syntax => :sass)
206
- end
207
-
208
- Sass::Engine.new(File.read(filename), options.merge(:filename => filename))
209
- end
210
-
211
- # The options for the Sass engine.
212
- # See {file:SASS_REFERENCE.md#sass_options the Sass options documentation}.
213
- #
214
- # @return [{Symbol => Object}]
215
- attr_reader :options
216
-
217
- # Creates a new Engine. Note that Engine should only be used directly
218
- # when compiling in-memory Sass code.
219
- # If you're compiling a single Sass file from the filesystem,
220
- # use \{Sass::Engine.for\_file}.
221
- # If you're compiling multiple files from the filesystem,
222
- # use {Sass::Plugin.
223
- #
224
- # @param template [String] The Sass template.
225
- # This template can be encoded using any encoding
226
- # that can be converted to Unicode.
227
- # If the template contains an `@charset` declaration,
228
- # that overrides the Ruby encoding
229
- # (see {file:SASS_REFERENCE.md#encodings the encoding documentation})
230
- # @param options [{Symbol => Object}] An options hash.
231
- # See {file:SASS_REFERENCE.md#sass_options the Sass options documentation}.
232
- # @see {Sass::Engine.for_file}
233
- # @see {Sass::Plugin}
234
- def initialize(template, options={})
235
- @options = self.class.normalize_options(options)
236
- @template = template
237
- end
238
-
239
- # Render the template to CSS.
240
- #
241
- # @return [String] The CSS
242
- # @raise [Sass::SyntaxError] if there's an error in the document
243
- # @raise [Encoding::UndefinedConversionError] if the source encoding
244
- # cannot be converted to UTF-8
245
- # @raise [ArgumentError] if the document uses an unknown encoding with `@charset`
246
- def render
247
- return _render unless @options[:quiet]
248
- Sass::Util.silence_sass_warnings {_render}
249
- end
250
- alias_method :to_css, :render
251
-
252
- # Parses the document into its parse tree. Memoized.
253
- #
254
- # @return [Sass::Tree::Node] The root of the parse tree.
255
- # @raise [Sass::SyntaxError] if there's an error in the document
256
- def to_tree
257
- @tree ||= @options[:quiet] ?
258
- Sass::Util.silence_sass_warnings {_to_tree} :
259
- _to_tree
260
- end
261
-
262
- # Returns the original encoding of the document,
263
- # or `nil` under Ruby 1.8.
264
- #
265
- # @return [Encoding, nil]
266
- # @raise [Encoding::UndefinedConversionError] if the source encoding
267
- # cannot be converted to UTF-8
268
- # @raise [ArgumentError] if the document uses an unknown encoding with `@charset`
269
- def source_encoding
270
- check_encoding!
271
- @original_encoding
272
- end
273
-
274
- # Gets a set of all the documents
275
- # that are (transitive) dependencies of this document,
276
- # not including the document itself.
277
- #
278
- # @return [[Sass::Engine]] The dependency documents.
279
- def dependencies
280
- _dependencies(Set.new, engines = Set.new)
281
- engines - [self]
282
- end
283
-
284
- # Helper for \{#dependencies}.
285
- #
286
- # @private
287
- def _dependencies(seen, engines)
288
- return if seen.include?(key = [@options[:filename], @options[:importer]])
289
- seen << key
290
- engines << self
291
- to_tree.grep(Tree::ImportNode) do |n|
292
- next if n.css_import?
293
- n.imported_file._dependencies(seen, engines)
294
- end
295
- end
296
-
297
- private
298
-
299
- def _render
300
- rendered = _to_tree.render
301
- return rendered if ruby1_8?
302
- begin
303
- # Try to convert the result to the original encoding,
304
- # but if that doesn't work fall back on UTF-8
305
- rendered = rendered.encode(source_encoding)
306
- rescue EncodingError
307
- end
308
- rendered.gsub(Regexp.new('\A@charset "(.*?)"'.encode(source_encoding)),
309
- "@charset \"#{source_encoding.name}\"".encode(source_encoding))
310
- end
311
-
312
- def _to_tree
313
- if (@options[:cache] || @options[:read_cache]) &&
314
- @options[:filename] && @options[:importer]
315
- key = sassc_key
316
- sha = Digest::SHA1.hexdigest(@template)
317
-
318
- if root = @options[:cache_store].retrieve(key, sha)
319
- root.options = @options
320
- return root
321
- end
322
- end
323
-
324
- check_encoding!
325
-
326
- if @options[:syntax] == :scss
327
- root = Sass::SCSS::Parser.new(@template, @options[:filename]).parse
328
- else
329
- root = Tree::RootNode.new(@template)
330
- append_children(root, tree(tabulate(@template)).first, true)
331
- end
332
-
333
- root.options = @options
334
- if @options[:cache] && key && sha
335
- begin
336
- old_options = root.options
337
- root.options = {}
338
- @options[:cache_store].store(key, sha, root)
339
- ensure
340
- root.options = old_options
341
- end
342
- end
343
- root
344
- rescue SyntaxError => e
345
- e.modify_backtrace(:filename => @options[:filename], :line => @line)
346
- e.sass_template = @template
347
- raise e
348
- end
349
-
350
- def sassc_key
351
- @options[:cache_store].key(*@options[:importer].key(@options[:filename], @options))
352
- end
353
-
354
- def check_encoding!
355
- return if @checked_encoding
356
- @checked_encoding = true
357
- @template, @original_encoding = check_sass_encoding(@template) do |msg, line|
358
- raise Sass::SyntaxError.new(msg, :line => line)
359
- end
360
- end
361
-
362
- def tabulate(string)
363
- tab_str = nil
364
- comment_tab_str = nil
365
- first = true
366
- lines = []
367
- string.gsub(/\r|\n|\r\n|\r\n/, "\n").scan(/^[^\n]*?$/).each_with_index do |line, index|
368
- index += (@options[:line] || 1)
369
- if line.strip.empty?
370
- lines.last.text << "\n" if lines.last && lines.last.comment?
371
- next
372
- end
373
-
374
- line_tab_str = line[/^\s*/]
375
- unless line_tab_str.empty?
376
- if tab_str.nil?
377
- comment_tab_str ||= line_tab_str
378
- next if try_comment(line, lines.last, "", comment_tab_str, index)
379
- comment_tab_str = nil
380
- end
381
-
382
- tab_str ||= line_tab_str
383
-
384
- raise SyntaxError.new("Indenting at the beginning of the document is illegal.",
385
- :line => index) if first
386
-
387
- raise SyntaxError.new("Indentation can't use both tabs and spaces.",
388
- :line => index) if tab_str.include?(?\s) && tab_str.include?(?\t)
389
- end
390
- first &&= !tab_str.nil?
391
- if tab_str.nil?
392
- lines << Line.new(line.strip, 0, index, 0, @options[:filename], [])
393
- next
394
- end
395
-
396
- comment_tab_str ||= line_tab_str
397
- if try_comment(line, lines.last, tab_str * lines.last.tabs, comment_tab_str, index)
398
- next
399
- else
400
- comment_tab_str = nil
401
- end
402
-
403
- line_tabs = line_tab_str.scan(tab_str).size
404
- if tab_str * line_tabs != line_tab_str
405
- message = <<END.strip.gsub("\n", ' ')
406
- Inconsistent indentation: #{Sass::Shared.human_indentation line_tab_str, true} used for indentation,
407
- but the rest of the document was indented using #{Sass::Shared.human_indentation tab_str}.
408
- END
409
- raise SyntaxError.new(message, :line => index)
410
- end
411
-
412
- lines << Line.new(line.strip, line_tabs, index, tab_str.size, @options[:filename], [])
413
- end
414
- lines
415
- end
416
-
417
- def try_comment(line, last, tab_str, comment_tab_str, index)
418
- return unless last && last.comment?
419
- # Nested comment stuff must be at least one whitespace char deeper
420
- # than the normal indentation
421
- return unless line =~ /^#{tab_str}\s/
422
- unless line =~ /^(?:#{comment_tab_str})(.*)$/
423
- raise SyntaxError.new(<<MSG.strip.gsub("\n", " "), :line => index)
424
- Inconsistent indentation:
425
- previous line was indented by #{Sass::Shared.human_indentation comment_tab_str},
426
- but this line was indented by #{Sass::Shared.human_indentation line[/^\s*/]}.
427
- MSG
428
- end
429
-
430
- last.comment_tab_str ||= comment_tab_str
431
- last.text << "\n" << line
432
- true
433
- end
434
-
435
- def tree(arr, i = 0)
436
- return [], i if arr[i].nil?
437
-
438
- base = arr[i].tabs
439
- nodes = []
440
- while (line = arr[i]) && line.tabs >= base
441
- if line.tabs > base
442
- raise SyntaxError.new("The line was indented #{line.tabs - base} levels deeper than the previous line.",
443
- :line => line.index) if line.tabs > base + 1
444
-
445
- nodes.last.children, i = tree(arr, i)
446
- else
447
- nodes << line
448
- i += 1
449
- end
450
- end
451
- return nodes, i
452
- end
453
-
454
- def build_tree(parent, line, root = false)
455
- @line = line.index
456
- node_or_nodes = parse_line(parent, line, root)
457
-
458
- Array(node_or_nodes).each do |node|
459
- # Node is a symbol if it's non-outputting, like a variable assignment
460
- next unless node.is_a? Tree::Node
461
-
462
- node.line = line.index
463
- node.filename = line.filename
464
-
465
- append_children(node, line.children, false)
466
- end
467
-
468
- node_or_nodes
469
- end
470
-
471
- def append_children(parent, children, root)
472
- continued_rule = nil
473
- continued_comment = nil
474
- children.each do |line|
475
- child = build_tree(parent, line, root)
476
-
477
- if child.is_a?(Tree::RuleNode)
478
- if child.continued? && child.children.empty?
479
- if continued_rule
480
- continued_rule.add_rules child
481
- else
482
- continued_rule = child
483
- end
484
- next
485
- elsif continued_rule
486
- continued_rule.add_rules child
487
- continued_rule.children = child.children
488
- continued_rule, child = nil, continued_rule
489
- end
490
- elsif continued_rule
491
- continued_rule = nil
492
- end
493
-
494
- if child.is_a?(Tree::CommentNode) && child.silent
495
- if continued_comment &&
496
- child.line == continued_comment.line +
497
- continued_comment.lines + 1
498
- continued_comment.value += ["\n"] + child.value
499
- next
500
- end
501
-
502
- continued_comment = child
503
- end
504
-
505
- check_for_no_children(child)
506
- validate_and_append_child(parent, child, line, root)
507
- end
508
-
509
- parent
510
- end
511
-
512
- def validate_and_append_child(parent, child, line, root)
513
- case child
514
- when Array
515
- child.each {|c| validate_and_append_child(parent, c, line, root)}
516
- when Tree::Node
517
- parent << child
518
- end
519
- end
520
-
521
- def check_for_no_children(node)
522
- return unless node.is_a?(Tree::RuleNode) && node.children.empty?
523
- Sass::Util.sass_warn(<<WARNING.strip)
524
- WARNING on line #{node.line}#{" of #{node.filename}" if node.filename}:
525
- This selector doesn't have any properties and will not be rendered.
526
- WARNING
527
- end
528
-
529
- def parse_line(parent, line, root)
530
- case line.text[0]
531
- when PROPERTY_CHAR
532
- if line.text[1] == PROPERTY_CHAR ||
533
- (@options[:property_syntax] == :new &&
534
- line.text =~ PROPERTY_OLD && $2.empty?)
535
- # Support CSS3-style pseudo-elements,
536
- # which begin with ::,
537
- # as well as pseudo-classes
538
- # if we're using the new property syntax
539
- Tree::RuleNode.new(parse_interp(line.text))
540
- else
541
- name, value = line.text.scan(PROPERTY_OLD)[0]
542
- raise SyntaxError.new("Invalid property: \"#{line.text}\".",
543
- :line => @line) if name.nil? || value.nil?
544
- parse_property(name, parse_interp(name), value, :old, line)
545
- end
546
- when ?$
547
- parse_variable(line)
548
- when COMMENT_CHAR
549
- parse_comment(line)
550
- when DIRECTIVE_CHAR
551
- parse_directive(parent, line, root)
552
- when ESCAPE_CHAR
553
- Tree::RuleNode.new(parse_interp(line.text[1..-1]))
554
- when MIXIN_DEFINITION_CHAR
555
- parse_mixin_definition(line)
556
- when MIXIN_INCLUDE_CHAR
557
- if line.text[1].nil? || line.text[1] == ?\s
558
- Tree::RuleNode.new(parse_interp(line.text))
559
- else
560
- parse_mixin_include(line, root)
561
- end
562
- else
563
- parse_property_or_rule(line)
564
- end
565
- end
566
-
567
- def parse_property_or_rule(line)
568
- scanner = StringScanner.new(line.text)
569
- hack_char = scanner.scan(/[:\*\.]|\#(?!\{)/)
570
- parser = Sass::SCSS::SassParser.new(scanner, @options[:filename], @line)
571
-
572
- unless res = parser.parse_interp_ident
573
- return Tree::RuleNode.new(parse_interp(line.text))
574
- end
575
- res.unshift(hack_char) if hack_char
576
- if comment = scanner.scan(Sass::SCSS::RX::COMMENT)
577
- res << comment
578
- end
579
-
580
- name = line.text[0...scanner.pos]
581
- if scanner.scan(/\s*:(?:\s|$)/)
582
- parse_property(name, res, scanner.rest, :new, line)
583
- else
584
- res.pop if comment
585
- Tree::RuleNode.new(res + parse_interp(scanner.rest))
586
- end
587
- end
588
-
589
- def parse_property(name, parsed_name, value, prop, line)
590
- if value.strip.empty?
591
- expr = Sass::Script::String.new("")
592
- else
593
- expr = parse_script(value, :offset => line.offset + line.text.index(value))
594
- end
595
- Tree::PropNode.new(parse_interp(name), expr, prop)
596
- end
597
-
598
- def parse_variable(line)
599
- name, value, default = line.text.scan(Script::MATCH)[0]
600
- raise SyntaxError.new("Illegal nesting: Nothing may be nested beneath variable declarations.",
601
- :line => @line + 1) unless line.children.empty?
602
- raise SyntaxError.new("Invalid variable: \"#{line.text}\".",
603
- :line => @line) unless name && value
604
-
605
- expr = parse_script(value, :offset => line.offset + line.text.index(value))
606
-
607
- Tree::VariableNode.new(name, expr, default)
608
- end
609
-
610
- def parse_comment(line)
611
- if line.text[1] == CSS_COMMENT_CHAR || line.text[1] == SASS_COMMENT_CHAR
612
- silent = line.text[1] == SASS_COMMENT_CHAR
613
- if loud = line.text[2] == SASS_LOUD_COMMENT_CHAR
614
- value = self.class.parse_interp(line.text, line.index, line.offset, :filename => @filename)
615
- value[0].slice!(2) # get rid of the "!"
616
- else
617
- value = [line.text]
618
- end
619
- value = with_extracted_values(value) do |str|
620
- str = str.gsub(/^#{line.comment_tab_str}/m, '')[2..-1] # get rid of // or /*
621
- format_comment_text(str, silent)
622
- end
623
- Tree::CommentNode.new(value, silent, loud)
624
- else
625
- Tree::RuleNode.new(parse_interp(line))
626
- end
627
- end
628
-
629
- def parse_directive(parent, line, root)
630
- directive, whitespace, value = line.text[1..-1].split(/(\s+)/, 2)
631
- offset = directive.size + whitespace.size + 1 if whitespace
632
-
633
- # If value begins with url( or ",
634
- # it's a CSS @import rule and we don't want to touch it.
635
- if directive == "import"
636
- parse_import(line, value)
637
- elsif directive == "mixin"
638
- parse_mixin_definition(line)
639
- elsif directive == "include"
640
- parse_mixin_include(line, root)
641
- elsif directive == "function"
642
- parse_function(line, root)
643
- elsif directive == "for"
644
- parse_for(line, root, value)
645
- elsif directive == "each"
646
- parse_each(line, root, value)
647
- elsif directive == "else"
648
- parse_else(parent, line, value)
649
- elsif directive == "while"
650
- raise SyntaxError.new("Invalid while directive '@while': expected expression.") unless value
651
- Tree::WhileNode.new(parse_script(value, :offset => offset))
652
- elsif directive == "if"
653
- raise SyntaxError.new("Invalid if directive '@if': expected expression.") unless value
654
- Tree::IfNode.new(parse_script(value, :offset => offset))
655
- elsif directive == "debug"
656
- raise SyntaxError.new("Invalid debug directive '@debug': expected expression.") unless value
657
- raise SyntaxError.new("Illegal nesting: Nothing may be nested beneath debug directives.",
658
- :line => @line + 1) unless line.children.empty?
659
- offset = line.offset + line.text.index(value).to_i
660
- Tree::DebugNode.new(parse_script(value, :offset => offset))
661
- elsif directive == "extend"
662
- raise SyntaxError.new("Invalid extend directive '@extend': expected expression.") unless value
663
- raise SyntaxError.new("Illegal nesting: Nothing may be nested beneath extend directives.",
664
- :line => @line + 1) unless line.children.empty?
665
- offset = line.offset + line.text.index(value).to_i
666
- Tree::ExtendNode.new(parse_interp(value, offset))
667
- elsif directive == "warn"
668
- raise SyntaxError.new("Invalid warn directive '@warn': expected expression.") unless value
669
- raise SyntaxError.new("Illegal nesting: Nothing may be nested beneath warn directives.",
670
- :line => @line + 1) unless line.children.empty?
671
- offset = line.offset + line.text.index(value).to_i
672
- Tree::WarnNode.new(parse_script(value, :offset => offset))
673
- elsif directive == "return"
674
- raise SyntaxError.new("Invalid @return: expected expression.") unless value
675
- raise SyntaxError.new("Illegal nesting: Nothing may be nested beneath return directives.",
676
- :line => @line + 1) unless line.children.empty?
677
- offset = line.offset + line.text.index(value).to_i
678
- Tree::ReturnNode.new(parse_script(value, :offset => offset))
679
- elsif directive == "charset"
680
- name = value && value[/\A(["'])(.*)\1\Z/, 2] #"
681
- raise SyntaxError.new("Invalid charset directive '@charset': expected string.") unless name
682
- raise SyntaxError.new("Illegal nesting: Nothing may be nested beneath charset directives.",
683
- :line => @line + 1) unless line.children.empty?
684
- Tree::CharsetNode.new(name)
685
- elsif directive == "media"
686
- Tree::MediaNode.new(value)
687
- else
688
- Tree::DirectiveNode.new(line.text)
689
- end
690
- end
691
-
692
- def parse_for(line, root, text)
693
- var, from_expr, to_name, to_expr = text.scan(/^([^\s]+)\s+from\s+(.+)\s+(to|through)\s+(.+)$/).first
694
-
695
- if var.nil? # scan failed, try to figure out why for error message
696
- if text !~ /^[^\s]+/
697
- expected = "variable name"
698
- elsif text !~ /^[^\s]+\s+from\s+.+/
699
- expected = "'from <expr>'"
700
- else
701
- expected = "'to <expr>' or 'through <expr>'"
702
- end
703
- raise SyntaxError.new("Invalid for directive '@for #{text}': expected #{expected}.")
704
- end
705
- raise SyntaxError.new("Invalid variable \"#{var}\".") unless var =~ Script::VALIDATE
706
-
707
- var = var[1..-1]
708
- parsed_from = parse_script(from_expr, :offset => line.offset + line.text.index(from_expr))
709
- parsed_to = parse_script(to_expr, :offset => line.offset + line.text.index(to_expr))
710
- Tree::ForNode.new(var, parsed_from, parsed_to, to_name == 'to')
711
- end
712
-
713
- def parse_each(line, root, text)
714
- var, list_expr = text.scan(/^([^\s]+)\s+in\s+(.+)$/).first
715
-
716
- if var.nil? # scan failed, try to figure out why for error message
717
- if text !~ /^[^\s]+/
718
- expected = "variable name"
719
- elsif text !~ /^[^\s]+\s+from\s+.+/
720
- expected = "'in <expr>'"
721
- end
722
- raise SyntaxError.new("Invalid for directive '@each #{text}': expected #{expected}.")
723
- end
724
- raise SyntaxError.new("Invalid variable \"#{var}\".") unless var =~ Script::VALIDATE
725
-
726
- var = var[1..-1]
727
- parsed_list = parse_script(list_expr, :offset => line.offset + line.text.index(list_expr))
728
- Tree::EachNode.new(var, parsed_list)
729
- end
730
-
731
- def parse_else(parent, line, text)
732
- previous = parent.children.last
733
- raise SyntaxError.new("@else must come after @if.") unless previous.is_a?(Tree::IfNode)
734
-
735
- if text
736
- if text !~ /^if\s+(.+)/
737
- raise SyntaxError.new("Invalid else directive '@else #{text}': expected 'if <expr>'.")
738
- end
739
- expr = parse_script($1, :offset => line.offset + line.text.index($1))
740
- end
741
-
742
- node = Tree::IfNode.new(expr)
743
- append_children(node, line.children, false)
744
- previous.add_else node
745
- nil
746
- end
747
-
748
- def parse_import(line, value)
749
- raise SyntaxError.new("Illegal nesting: Nothing may be nested beneath import directives.",
750
- :line => @line + 1) unless line.children.empty?
751
-
752
- scanner = StringScanner.new(value)
753
- values = []
754
-
755
- loop do
756
- unless node = parse_import_arg(scanner)
757
- raise SyntaxError.new("Invalid @import: expected file to import, was #{scanner.rest.inspect}",
758
- :line => @line)
759
- end
760
- values << node
761
- break unless scanner.scan(/,\s*/)
762
- end
763
-
764
- if scanner.scan(/;/)
765
- raise SyntaxError.new("Invalid @import: expected end of line, was \";\".",
766
- :line => @line)
767
- end
768
-
769
- return values
770
- end
771
-
772
- def parse_import_arg(scanner)
773
- return if scanner.eos?
774
- unless (str = scanner.scan(Sass::SCSS::RX::STRING)) ||
775
- (uri = scanner.scan(Sass::SCSS::RX::URI))
776
- return Tree::ImportNode.new(scanner.scan(/[^,;]+/))
777
- end
778
-
779
- val = scanner[1] || scanner[2]
780
- scanner.scan(/\s*/)
781
- if media = scanner.scan(/[^,;].*/)
782
- Tree::DirectiveNode.new("@import #{str || uri} #{media}")
783
- elsif uri
784
- Tree::DirectiveNode.new("@import #{uri}")
785
- elsif val =~ /^http:\/\//
786
- Tree::DirectiveNode.new("@import url(#{val})")
787
- else
788
- Tree::ImportNode.new(val)
789
- end
790
- end
791
-
792
- MIXIN_DEF_RE = /^(?:=|@mixin)\s*(#{Sass::SCSS::RX::IDENT})(.*)$/
793
- def parse_mixin_definition(line)
794
- name, arg_string = line.text.scan(MIXIN_DEF_RE).first
795
- raise SyntaxError.new("Invalid mixin \"#{line.text[1..-1]}\".") if name.nil?
796
-
797
- offset = line.offset + line.text.size - arg_string.size
798
- args = Script::Parser.new(arg_string.strip, @line, offset, @options).
799
- parse_mixin_definition_arglist
800
- Tree::MixinDefNode.new(name, args)
801
- end
802
-
803
- MIXIN_INCLUDE_RE = /^(?:\+|@include)\s*(#{Sass::SCSS::RX::IDENT})(.*)$/
804
- def parse_mixin_include(line, root)
805
- name, arg_string = line.text.scan(MIXIN_INCLUDE_RE).first
806
- raise SyntaxError.new("Invalid mixin include \"#{line.text}\".") if name.nil?
807
-
808
- offset = line.offset + line.text.size - arg_string.size
809
- args, keywords = Script::Parser.new(arg_string.strip, @line, offset, @options).
810
- parse_mixin_include_arglist
811
- raise SyntaxError.new("Illegal nesting: Nothing may be nested beneath mixin directives.",
812
- :line => @line + 1) unless line.children.empty?
813
- Tree::MixinNode.new(name, args, keywords)
814
- end
815
-
816
- FUNCTION_RE = /^@function\s*(#{Sass::SCSS::RX::IDENT})(.*)$/
817
- def parse_function(line, root)
818
- name, arg_string = line.text.scan(FUNCTION_RE).first
819
- raise SyntaxError.new("Invalid function definition \"#{line.text}\".") if name.nil?
820
-
821
- offset = line.offset + line.text.size - arg_string.size
822
- args = Script::Parser.new(arg_string.strip, @line, offset, @options).
823
- parse_function_definition_arglist
824
- Tree::FunctionNode.new(name, args)
825
- end
826
-
827
- def parse_script(script, options = {})
828
- line = options[:line] || @line
829
- offset = options[:offset] || 0
830
- Script.parse(script, line, offset, @options)
831
- end
832
-
833
- def format_comment_text(text, silent)
834
- content = text.split("\n")
835
-
836
- if content.first && content.first.strip.empty?
837
- removed_first = true
838
- content.shift
839
- end
840
-
841
- return silent ? "//" : "/* */" if content.empty?
842
- content.last.gsub!(%r{ ?\*/ *$}, '')
843
- content.map! {|l| l.gsub!(/^\*( ?)/, '\1') || (l.empty? ? "" : " ") + l}
844
- content.first.gsub!(/^ /, '') unless removed_first
845
- if silent
846
- "//" + content.join("\n//")
847
- else
848
- # The #gsub fixes the case of a trailing */
849
- "/*" + content.join("\n *").gsub(/ \*\Z/, '') + " */"
850
- end
851
- end
852
-
853
- def parse_interp(text, offset = 0)
854
- self.class.parse_interp(text, @line, offset, :filename => @filename)
855
- end
856
-
857
- # It's important that this have strings (at least)
858
- # at the beginning, the end, and between each Script::Node.
859
- #
860
- # @private
861
- def self.parse_interp(text, line, offset, options)
862
- res = []
863
- rest = Sass::Shared.handle_interpolation text do |scan|
864
- escapes = scan[2].size
865
- res << scan.matched[0...-2 - escapes]
866
- if escapes % 2 == 1
867
- res << "\\" * (escapes - 1) << '#{'
868
- else
869
- res << "\\" * [0, escapes - 1].max
870
- res << Script::Parser.new(
871
- scan, line, offset + scan.pos - scan.matched_size, options).
872
- parse_interpolated
873
- end
874
- end
875
- res << rest
876
- end
877
- end
878
- end