haml_ejs 0.0.1

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 (358) hide show
  1. data/.yardopts +11 -0
  2. data/CONTRIBUTING +3 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.md +68 -0
  5. data/Rakefile +419 -0
  6. data/VERSION +1 -0
  7. data/VERSION_NAME +1 -0
  8. data/bin/haml +9 -0
  9. data/bin/html2haml +7 -0
  10. data/extra/update_watch.rb +13 -0
  11. data/init.rb +18 -0
  12. data/lib/haml.rb +49 -0
  13. data/lib/haml/buffer.rb +297 -0
  14. data/lib/haml/compiler.rb +486 -0
  15. data/lib/haml/engine.rb +312 -0
  16. data/lib/haml/error.rb +22 -0
  17. data/lib/haml/exec.rb +362 -0
  18. data/lib/haml/filters.rb +388 -0
  19. data/lib/haml/haml_ejs.rb +57 -0
  20. data/lib/haml/helpers.rb +608 -0
  21. data/lib/haml/helpers/action_view_extensions.rb +57 -0
  22. data/lib/haml/helpers/action_view_mods.rb +257 -0
  23. data/lib/haml/helpers/xss_mods.rb +165 -0
  24. data/lib/haml/html.rb +412 -0
  25. data/lib/haml/html/erb.rb +141 -0
  26. data/lib/haml/parser.rb +760 -0
  27. data/lib/haml/railtie.rb +19 -0
  28. data/lib/haml/root.rb +7 -0
  29. data/lib/haml/shared.rb +78 -0
  30. data/lib/haml/template.rb +99 -0
  31. data/lib/haml/template/options.rb +16 -0
  32. data/lib/haml/template/patch.rb +58 -0
  33. data/lib/haml/template/plugin.rb +123 -0
  34. data/lib/haml/util.rb +842 -0
  35. data/lib/haml/version.rb +109 -0
  36. data/lib/sass.rb +8 -0
  37. data/lib/sass/plugin.rb +10 -0
  38. data/lib/sass/rails2_shim.rb +9 -0
  39. data/lib/sass/rails3_shim.rb +16 -0
  40. data/rails/init.rb +1 -0
  41. data/test/benchmark.rb +91 -0
  42. data/test/gemfiles/Gemfile.rails-2.0.x +8 -0
  43. data/test/gemfiles/Gemfile.rails-2.0.x.lock +38 -0
  44. data/test/gemfiles/Gemfile.rails-2.1.x +8 -0
  45. data/test/gemfiles/Gemfile.rails-2.1.x.lock +38 -0
  46. data/test/gemfiles/Gemfile.rails-2.2.x +8 -0
  47. data/test/gemfiles/Gemfile.rails-2.2.x.lock +38 -0
  48. data/test/gemfiles/Gemfile.rails-2.3.x +8 -0
  49. data/test/gemfiles/Gemfile.rails-2.3.x.lock +40 -0
  50. data/test/gemfiles/Gemfile.rails-3.0.x +8 -0
  51. data/test/gemfiles/Gemfile.rails-3.0.x.lock +85 -0
  52. data/test/gemfiles/Gemfile.rails-3.1.x +8 -0
  53. data/test/gemfiles/Gemfile.rails-3.1.x.lock +98 -0
  54. data/test/gemfiles/Gemfile.rails-xss-2.3.x +9 -0
  55. data/test/gemfiles/Gemfile.rails-xss-2.3.x.lock +42 -0
  56. data/test/haml-ejs/haml-ejs_test.rb +22 -0
  57. data/test/haml-ejs/templates/conditional.input +3 -0
  58. data/test/haml-ejs/templates/conditional.output +3 -0
  59. data/test/haml-ejs/templates/conditional_and_interpolation.input +2 -0
  60. data/test/haml-ejs/templates/conditional_and_interpolation.output +3 -0
  61. data/test/haml-ejs/templates/conditional_else.input +5 -0
  62. data/test/haml-ejs/templates/conditional_else.output +5 -0
  63. data/test/haml-ejs/templates/conditional_else_elsif.input +7 -0
  64. data/test/haml-ejs/templates/conditional_else_elsif.output +7 -0
  65. data/test/haml-ejs/templates/conditional_elsif.input +5 -0
  66. data/test/haml-ejs/templates/conditional_elsif.output +5 -0
  67. data/test/haml-ejs/templates/conditional_unless.input +3 -0
  68. data/test/haml-ejs/templates/conditional_unless.output +3 -0
  69. data/test/haml-ejs/templates/conditional_unless_else.input +5 -0
  70. data/test/haml-ejs/templates/conditional_unless_else.output +5 -0
  71. data/test/haml-ejs/templates/conditional_unless_elsif_else.input +5 -0
  72. data/test/haml-ejs/templates/conditional_unless_elsif_else.output +5 -0
  73. data/test/haml-ejs/templates/interpolation.input +2 -0
  74. data/test/haml-ejs/templates/interpolation.output +1 -0
  75. data/test/haml-ejs/templates/iteration.input +2 -0
  76. data/test/haml-ejs/templates/iteration.output +3 -0
  77. data/test/haml-ejs/templates/suite.input +26 -0
  78. data/test/haml-ejs/templates/suite.output +27 -0
  79. data/test/haml/engine_test.rb +1925 -0
  80. data/test/haml/erb/_av_partial_1.erb +12 -0
  81. data/test/haml/erb/_av_partial_2.erb +8 -0
  82. data/test/haml/erb/action_view.erb +62 -0
  83. data/test/haml/erb/standard.erb +55 -0
  84. data/test/haml/helper_test.rb +454 -0
  85. data/test/haml/html2haml/erb_tests.rb +440 -0
  86. data/test/haml/html2haml_test.rb +336 -0
  87. data/test/haml/markaby/standard.mab +52 -0
  88. data/test/haml/mocks/article.rb +6 -0
  89. data/test/haml/results/content_for_layout.xhtml +12 -0
  90. data/test/haml/results/eval_suppressed.xhtml +9 -0
  91. data/test/haml/results/filters.xhtml +62 -0
  92. data/test/haml/results/helpers.xhtml +70 -0
  93. data/test/haml/results/helpful.xhtml +10 -0
  94. data/test/haml/results/just_stuff.xhtml +70 -0
  95. data/test/haml/results/list.xhtml +12 -0
  96. data/test/haml/results/nuke_inner_whitespace.xhtml +40 -0
  97. data/test/haml/results/nuke_outer_whitespace.xhtml +148 -0
  98. data/test/haml/results/original_engine.xhtml +20 -0
  99. data/test/haml/results/partial_layout.xhtml +5 -0
  100. data/test/haml/results/partials.xhtml +21 -0
  101. data/test/haml/results/render_layout.xhtml +3 -0
  102. data/test/haml/results/silent_script.xhtml +74 -0
  103. data/test/haml/results/standard.xhtml +162 -0
  104. data/test/haml/results/tag_parsing.xhtml +23 -0
  105. data/test/haml/results/very_basic.xhtml +5 -0
  106. data/test/haml/results/whitespace_handling.xhtml +89 -0
  107. data/test/haml/spec/README.md +97 -0
  108. data/test/haml/spec/lua_haml_spec.lua +30 -0
  109. data/test/haml/spec/ruby_haml_test.rb +19 -0
  110. data/test/haml/spec/tests.json +534 -0
  111. data/test/haml/spec_test.rb +44 -0
  112. data/test/haml/template_test.rb +419 -0
  113. data/test/haml/templates/_av_partial_1.haml +9 -0
  114. data/test/haml/templates/_av_partial_1_ugly.haml +9 -0
  115. data/test/haml/templates/_av_partial_2.haml +5 -0
  116. data/test/haml/templates/_av_partial_2_ugly.haml +5 -0
  117. data/test/haml/templates/_layout.erb +3 -0
  118. data/test/haml/templates/_layout_for_partial.haml +3 -0
  119. data/test/haml/templates/_partial.haml +8 -0
  120. data/test/haml/templates/_text_area.haml +3 -0
  121. data/test/haml/templates/action_view.haml +47 -0
  122. data/test/haml/templates/action_view_ugly.haml +47 -0
  123. data/test/haml/templates/breakage.haml +8 -0
  124. data/test/haml/templates/content_for_layout.haml +8 -0
  125. data/test/haml/templates/eval_suppressed.haml +11 -0
  126. data/test/haml/templates/filters.haml +66 -0
  127. data/test/haml/templates/helpers.haml +55 -0
  128. data/test/haml/templates/helpful.haml +11 -0
  129. data/test/haml/templates/just_stuff.haml +85 -0
  130. data/test/haml/templates/list.haml +12 -0
  131. data/test/haml/templates/nuke_inner_whitespace.haml +32 -0
  132. data/test/haml/templates/nuke_outer_whitespace.haml +144 -0
  133. data/test/haml/templates/original_engine.haml +17 -0
  134. data/test/haml/templates/partial_layout.haml +10 -0
  135. data/test/haml/templates/partialize.haml +1 -0
  136. data/test/haml/templates/partials.haml +12 -0
  137. data/test/haml/templates/render_layout.haml +2 -0
  138. data/test/haml/templates/silent_script.haml +40 -0
  139. data/test/haml/templates/standard.haml +43 -0
  140. data/test/haml/templates/standard_ugly.haml +43 -0
  141. data/test/haml/templates/tag_parsing.haml +21 -0
  142. data/test/haml/templates/very_basic.haml +4 -0
  143. data/test/haml/templates/whitespace_handling.haml +87 -0
  144. data/test/haml/util_test.rb +300 -0
  145. data/test/linked_rails.rb +42 -0
  146. data/test/test_helper.rb +75 -0
  147. data/vendor/sass/CONTRIBUTING +3 -0
  148. data/vendor/sass/MIT-LICENSE +20 -0
  149. data/vendor/sass/README.md +201 -0
  150. data/vendor/sass/Rakefile +339 -0
  151. data/vendor/sass/TODO +39 -0
  152. data/vendor/sass/VERSION +1 -0
  153. data/vendor/sass/VERSION_NAME +1 -0
  154. data/vendor/sass/bin/sass +8 -0
  155. data/vendor/sass/bin/sass-convert +7 -0
  156. data/vendor/sass/bin/scss +8 -0
  157. data/vendor/sass/doc-src/FAQ.md +35 -0
  158. data/vendor/sass/doc-src/INDENTED_SYNTAX.md +210 -0
  159. data/vendor/sass/doc-src/SASS_CHANGELOG.md +2214 -0
  160. data/vendor/sass/doc-src/SASS_REFERENCE.md +1957 -0
  161. data/vendor/sass/doc-src/SCSS_FOR_SASS_USERS.md +155 -0
  162. data/vendor/sass/ext/extconf.rb +10 -0
  163. data/vendor/sass/extra/update_watch.rb +13 -0
  164. data/vendor/sass/init.rb +18 -0
  165. data/vendor/sass/lib/sass.rb +72 -0
  166. data/vendor/sass/lib/sass/cache_stores.rb +15 -0
  167. data/vendor/sass/lib/sass/cache_stores/base.rb +84 -0
  168. data/vendor/sass/lib/sass/cache_stores/chain.rb +33 -0
  169. data/vendor/sass/lib/sass/cache_stores/filesystem.rb +58 -0
  170. data/vendor/sass/lib/sass/cache_stores/memory.rb +47 -0
  171. data/vendor/sass/lib/sass/cache_stores/null.rb +25 -0
  172. data/vendor/sass/lib/sass/callbacks.rb +66 -0
  173. data/vendor/sass/lib/sass/css.rb +294 -0
  174. data/vendor/sass/lib/sass/engine.rb +862 -0
  175. data/vendor/sass/lib/sass/environment.rb +155 -0
  176. data/vendor/sass/lib/sass/error.rb +201 -0
  177. data/vendor/sass/lib/sass/exec.rb +659 -0
  178. data/vendor/sass/lib/sass/importers.rb +22 -0
  179. data/vendor/sass/lib/sass/importers/base.rb +138 -0
  180. data/vendor/sass/lib/sass/importers/filesystem.rb +144 -0
  181. data/vendor/sass/lib/sass/less.rb +382 -0
  182. data/vendor/sass/lib/sass/plugin.rb +136 -0
  183. data/vendor/sass/lib/sass/plugin/compiler.rb +358 -0
  184. data/vendor/sass/lib/sass/plugin/configuration.rb +125 -0
  185. data/vendor/sass/lib/sass/plugin/generic.rb +15 -0
  186. data/vendor/sass/lib/sass/plugin/merb.rb +48 -0
  187. data/vendor/sass/lib/sass/plugin/rack.rb +60 -0
  188. data/vendor/sass/lib/sass/plugin/rails.rb +47 -0
  189. data/vendor/sass/lib/sass/plugin/staleness_checker.rb +173 -0
  190. data/vendor/sass/lib/sass/railtie.rb +9 -0
  191. data/vendor/sass/lib/sass/repl.rb +58 -0
  192. data/vendor/sass/lib/sass/root.rb +7 -0
  193. data/vendor/sass/lib/sass/script.rb +40 -0
  194. data/vendor/sass/lib/sass/script/bool.rb +18 -0
  195. data/vendor/sass/lib/sass/script/color.rb +480 -0
  196. data/vendor/sass/lib/sass/script/css_lexer.rb +29 -0
  197. data/vendor/sass/lib/sass/script/css_parser.rb +31 -0
  198. data/vendor/sass/lib/sass/script/funcall.rb +162 -0
  199. data/vendor/sass/lib/sass/script/functions.rb +1343 -0
  200. data/vendor/sass/lib/sass/script/interpolation.rb +70 -0
  201. data/vendor/sass/lib/sass/script/lexer.rb +334 -0
  202. data/vendor/sass/lib/sass/script/list.rb +76 -0
  203. data/vendor/sass/lib/sass/script/literal.rb +245 -0
  204. data/vendor/sass/lib/sass/script/node.rb +91 -0
  205. data/vendor/sass/lib/sass/script/number.rb +429 -0
  206. data/vendor/sass/lib/sass/script/operation.rb +91 -0
  207. data/vendor/sass/lib/sass/script/parser.rb +467 -0
  208. data/vendor/sass/lib/sass/script/string.rb +51 -0
  209. data/vendor/sass/lib/sass/script/string_interpolation.rb +94 -0
  210. data/vendor/sass/lib/sass/script/unary_operation.rb +57 -0
  211. data/vendor/sass/lib/sass/script/variable.rb +54 -0
  212. data/vendor/sass/lib/sass/scss.rb +17 -0
  213. data/vendor/sass/lib/sass/scss/css_parser.rb +46 -0
  214. data/vendor/sass/lib/sass/scss/parser.rb +920 -0
  215. data/vendor/sass/lib/sass/scss/rx.rb +127 -0
  216. data/vendor/sass/lib/sass/scss/sass_parser.rb +11 -0
  217. data/vendor/sass/lib/sass/scss/script_lexer.rb +15 -0
  218. data/vendor/sass/lib/sass/scss/script_parser.rb +25 -0
  219. data/vendor/sass/lib/sass/scss/static_parser.rb +40 -0
  220. data/vendor/sass/lib/sass/selector.rb +361 -0
  221. data/vendor/sass/lib/sass/selector/abstract_sequence.rb +62 -0
  222. data/vendor/sass/lib/sass/selector/comma_sequence.rb +81 -0
  223. data/vendor/sass/lib/sass/selector/sequence.rb +233 -0
  224. data/vendor/sass/lib/sass/selector/simple.rb +113 -0
  225. data/vendor/sass/lib/sass/selector/simple_sequence.rb +134 -0
  226. data/vendor/sass/lib/sass/shared.rb +78 -0
  227. data/vendor/sass/lib/sass/tree/charset_node.rb +22 -0
  228. data/vendor/sass/lib/sass/tree/comment_node.rb +77 -0
  229. data/vendor/sass/lib/sass/tree/debug_node.rb +18 -0
  230. data/vendor/sass/lib/sass/tree/directive_node.rb +23 -0
  231. data/vendor/sass/lib/sass/tree/each_node.rb +24 -0
  232. data/vendor/sass/lib/sass/tree/extend_node.rb +29 -0
  233. data/vendor/sass/lib/sass/tree/for_node.rb +36 -0
  234. data/vendor/sass/lib/sass/tree/function_node.rb +27 -0
  235. data/vendor/sass/lib/sass/tree/if_node.rb +65 -0
  236. data/vendor/sass/lib/sass/tree/import_node.rb +68 -0
  237. data/vendor/sass/lib/sass/tree/media_node.rb +32 -0
  238. data/vendor/sass/lib/sass/tree/mixin_def_node.rb +27 -0
  239. data/vendor/sass/lib/sass/tree/mixin_node.rb +32 -0
  240. data/vendor/sass/lib/sass/tree/node.rb +204 -0
  241. data/vendor/sass/lib/sass/tree/prop_node.rb +155 -0
  242. data/vendor/sass/lib/sass/tree/return_node.rb +18 -0
  243. data/vendor/sass/lib/sass/tree/root_node.rb +28 -0
  244. data/vendor/sass/lib/sass/tree/rule_node.rb +129 -0
  245. data/vendor/sass/lib/sass/tree/variable_node.rb +30 -0
  246. data/vendor/sass/lib/sass/tree/visitors/base.rb +75 -0
  247. data/vendor/sass/lib/sass/tree/visitors/check_nesting.rb +134 -0
  248. data/vendor/sass/lib/sass/tree/visitors/convert.rb +255 -0
  249. data/vendor/sass/lib/sass/tree/visitors/cssize.rb +175 -0
  250. data/vendor/sass/lib/sass/tree/visitors/perform.rb +301 -0
  251. data/vendor/sass/lib/sass/tree/visitors/to_css.rb +216 -0
  252. data/vendor/sass/lib/sass/tree/warn_node.rb +18 -0
  253. data/vendor/sass/lib/sass/tree/while_node.rb +18 -0
  254. data/vendor/sass/lib/sass/util.rb +669 -0
  255. data/vendor/sass/lib/sass/util/subset_map.rb +101 -0
  256. data/vendor/sass/lib/sass/version.rb +112 -0
  257. data/vendor/sass/rails/init.rb +1 -0
  258. data/vendor/sass/sass.gemspec +32 -0
  259. data/vendor/sass/test/sass/cache_test.rb +74 -0
  260. data/vendor/sass/test/sass/callbacks_test.rb +61 -0
  261. data/vendor/sass/test/sass/conversion_test.rb +1203 -0
  262. data/vendor/sass/test/sass/css2sass_test.rb +364 -0
  263. data/vendor/sass/test/sass/data/hsl-rgb.txt +319 -0
  264. data/vendor/sass/test/sass/engine_test.rb +2469 -0
  265. data/vendor/sass/test/sass/extend_test.rb +1348 -0
  266. data/vendor/sass/test/sass/functions_test.rb +1025 -0
  267. data/vendor/sass/test/sass/importer_test.rb +82 -0
  268. data/vendor/sass/test/sass/less_conversion_test.rb +653 -0
  269. data/vendor/sass/test/sass/mock_importer.rb +49 -0
  270. data/vendor/sass/test/sass/more_results/more1.css +9 -0
  271. data/vendor/sass/test/sass/more_results/more1_with_line_comments.css +26 -0
  272. data/vendor/sass/test/sass/more_results/more_import.css +29 -0
  273. data/vendor/sass/test/sass/more_templates/_more_partial.sass +2 -0
  274. data/vendor/sass/test/sass/more_templates/more1.sass +23 -0
  275. data/vendor/sass/test/sass/more_templates/more_import.sass +11 -0
  276. data/vendor/sass/test/sass/plugin_test.rb +469 -0
  277. data/vendor/sass/test/sass/results/alt.css +4 -0
  278. data/vendor/sass/test/sass/results/basic.css +9 -0
  279. data/vendor/sass/test/sass/results/compact.css +5 -0
  280. data/vendor/sass/test/sass/results/complex.css +86 -0
  281. data/vendor/sass/test/sass/results/compressed.css +1 -0
  282. data/vendor/sass/test/sass/results/expanded.css +19 -0
  283. data/vendor/sass/test/sass/results/if.css +3 -0
  284. data/vendor/sass/test/sass/results/import.css +31 -0
  285. data/vendor/sass/test/sass/results/import_charset.css +4 -0
  286. data/vendor/sass/test/sass/results/import_charset_1_8.css +4 -0
  287. data/vendor/sass/test/sass/results/import_charset_ibm866.css +4 -0
  288. data/vendor/sass/test/sass/results/line_numbers.css +49 -0
  289. data/vendor/sass/test/sass/results/mixins.css +95 -0
  290. data/vendor/sass/test/sass/results/multiline.css +24 -0
  291. data/vendor/sass/test/sass/results/nested.css +22 -0
  292. data/vendor/sass/test/sass/results/options.css +1 -0
  293. data/vendor/sass/test/sass/results/parent_ref.css +13 -0
  294. data/vendor/sass/test/sass/results/script.css +16 -0
  295. data/vendor/sass/test/sass/results/scss_import.css +31 -0
  296. data/vendor/sass/test/sass/results/scss_importee.css +2 -0
  297. data/vendor/sass/test/sass/results/subdir/nested_subdir/nested_subdir.css +1 -0
  298. data/vendor/sass/test/sass/results/subdir/subdir.css +3 -0
  299. data/vendor/sass/test/sass/results/units.css +11 -0
  300. data/vendor/sass/test/sass/results/warn.css +0 -0
  301. data/vendor/sass/test/sass/results/warn_imported.css +0 -0
  302. data/vendor/sass/test/sass/script_conversion_test.rb +283 -0
  303. data/vendor/sass/test/sass/script_test.rb +496 -0
  304. data/vendor/sass/test/sass/scss/css_test.rb +916 -0
  305. data/vendor/sass/test/sass/scss/rx_test.rb +156 -0
  306. data/vendor/sass/test/sass/scss/scss_test.rb +1249 -0
  307. data/vendor/sass/test/sass/scss/test_helper.rb +37 -0
  308. data/vendor/sass/test/sass/templates/_imported_charset_ibm866.sass +4 -0
  309. data/vendor/sass/test/sass/templates/_imported_charset_utf8.sass +4 -0
  310. data/vendor/sass/test/sass/templates/_partial.sass +2 -0
  311. data/vendor/sass/test/sass/templates/alt.sass +16 -0
  312. data/vendor/sass/test/sass/templates/basic.sass +23 -0
  313. data/vendor/sass/test/sass/templates/bork1.sass +2 -0
  314. data/vendor/sass/test/sass/templates/bork2.sass +2 -0
  315. data/vendor/sass/test/sass/templates/bork3.sass +2 -0
  316. data/vendor/sass/test/sass/templates/bork4.sass +2 -0
  317. data/vendor/sass/test/sass/templates/compact.sass +17 -0
  318. data/vendor/sass/test/sass/templates/complex.sass +305 -0
  319. data/vendor/sass/test/sass/templates/compressed.sass +15 -0
  320. data/vendor/sass/test/sass/templates/expanded.sass +17 -0
  321. data/vendor/sass/test/sass/templates/if.sass +11 -0
  322. data/vendor/sass/test/sass/templates/import.sass +12 -0
  323. data/vendor/sass/test/sass/templates/import_charset.sass +7 -0
  324. data/vendor/sass/test/sass/templates/import_charset_1_8.sass +4 -0
  325. data/vendor/sass/test/sass/templates/import_charset_ibm866.sass +9 -0
  326. data/vendor/sass/test/sass/templates/importee.less +2 -0
  327. data/vendor/sass/test/sass/templates/importee.sass +19 -0
  328. data/vendor/sass/test/sass/templates/line_numbers.sass +13 -0
  329. data/vendor/sass/test/sass/templates/mixin_bork.sass +5 -0
  330. data/vendor/sass/test/sass/templates/mixins.sass +76 -0
  331. data/vendor/sass/test/sass/templates/multiline.sass +20 -0
  332. data/vendor/sass/test/sass/templates/nested.sass +25 -0
  333. data/vendor/sass/test/sass/templates/nested_bork1.sass +2 -0
  334. data/vendor/sass/test/sass/templates/nested_bork2.sass +2 -0
  335. data/vendor/sass/test/sass/templates/nested_bork3.sass +2 -0
  336. data/vendor/sass/test/sass/templates/nested_bork4.sass +2 -0
  337. data/vendor/sass/test/sass/templates/nested_import.sass +2 -0
  338. data/vendor/sass/test/sass/templates/nested_mixin_bork.sass +6 -0
  339. data/vendor/sass/test/sass/templates/options.sass +2 -0
  340. data/vendor/sass/test/sass/templates/parent_ref.sass +25 -0
  341. data/vendor/sass/test/sass/templates/script.sass +101 -0
  342. data/vendor/sass/test/sass/templates/scss_import.scss +11 -0
  343. data/vendor/sass/test/sass/templates/scss_importee.scss +1 -0
  344. data/vendor/sass/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +2 -0
  345. data/vendor/sass/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +3 -0
  346. data/vendor/sass/test/sass/templates/subdir/subdir.sass +6 -0
  347. data/vendor/sass/test/sass/templates/units.sass +11 -0
  348. data/vendor/sass/test/sass/templates/warn.sass +3 -0
  349. data/vendor/sass/test/sass/templates/warn_imported.sass +4 -0
  350. data/vendor/sass/test/sass/test_helper.rb +8 -0
  351. data/vendor/sass/test/sass/util/subset_map_test.rb +91 -0
  352. data/vendor/sass/test/sass/util_test.rb +254 -0
  353. data/vendor/sass/test/test_helper.rb +69 -0
  354. data/vendor/sass/yard/callbacks.rb +29 -0
  355. data/vendor/sass/yard/default/fulldoc/html/css/common.sass +26 -0
  356. data/vendor/sass/yard/default/layout/html/footer.erb +12 -0
  357. data/vendor/sass/yard/inherited_hash.rb +41 -0
  358. metadata +458 -0
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
data/VERSION_NAME ADDED
@@ -0,0 +1 @@
1
+ Bleeding Edge
data/bin/haml ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+ # The command line Haml parser.
3
+
4
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
5
+ require 'haml'
6
+ require 'haml/exec'
7
+
8
+ opts = Haml::Exec::Haml.new(ARGV)
9
+ opts.parse!
data/bin/html2haml ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.dirname(__FILE__) + '/../lib/haml'
4
+ require 'haml/exec'
5
+
6
+ opts = Haml::Exec::HTML2Haml.new(ARGV)
7
+ opts.parse!
@@ -0,0 +1,13 @@
1
+ require 'rubygems'
2
+ require 'sinatra'
3
+ require 'json'
4
+ set :port, 3123
5
+ set :environment, :production
6
+ enable :lock
7
+ Dir.chdir(File.dirname(__FILE__) + "/..")
8
+
9
+ post "/" do
10
+ puts "Recieved payload!"
11
+ puts "Rev: #{`git name-rev HEAD`.strip}"
12
+ system %{rake handle_update --trace REF=#{JSON.parse(params["payload"])["ref"].inspect}}
13
+ end
data/init.rb ADDED
@@ -0,0 +1,18 @@
1
+ begin
2
+ require File.join(File.dirname(__FILE__), 'lib', 'haml') # From here
3
+ rescue LoadError
4
+ begin
5
+ require 'haml' # From gem
6
+ rescue LoadError => e
7
+ # gems:install may be run to install Haml with the skeleton plugin
8
+ # but not the gem itself installed.
9
+ # Don't die if this is the case.
10
+ raise e unless defined?(Rake) &&
11
+ (Rake.application.top_level_tasks.include?('gems') ||
12
+ Rake.application.top_level_tasks.include?('gems:install'))
13
+ end
14
+ end
15
+
16
+ # Load Haml.
17
+ # Haml may be undefined if we're running gems:install.
18
+ Haml.init_rails(binding) if defined?(Haml)
data/lib/haml.rb ADDED
@@ -0,0 +1,49 @@
1
+ dir = File.dirname(__FILE__)
2
+ $LOAD_PATH.unshift dir unless $LOAD_PATH.include?(dir)
3
+
4
+ require 'haml/version'
5
+
6
+ # The module that contains everything Haml-related:
7
+ #
8
+ # * {Haml::Engine} is the class used to render Haml within Ruby code.
9
+ # * {Haml::Helpers} contains Ruby helpers available within Haml templates.
10
+ # * {Haml::Template} interfaces with web frameworks (Rails in particular).
11
+ # * {Haml::Error} is raised when Haml encounters an error.
12
+ # * {Haml::HTML} handles conversion of HTML to Haml.
13
+ #
14
+ # Also see the {file:HAML_REFERENCE.md full Haml reference}.
15
+ module Haml
16
+ # Initializes Haml for Rails.
17
+ #
18
+ # This method is called by `init.rb`,
19
+ # which is run by Rails on startup.
20
+ # We use it rather than putting stuff straight into `init.rb`
21
+ # so we can change the initialization behavior
22
+ # without modifying the file itself.
23
+ #
24
+ # @param binding [Binding] The context of the `init.rb` file.
25
+ # This isn't actually used;
26
+ # it's just passed in in case it needs to be used in the future
27
+ def self.init_rails(binding)
28
+ # 2.2 <= Rails < 3
29
+ if defined?(Rails) && Rails.respond_to?(:configuration) &&
30
+ Rails.configuration.respond_to?(:after_initialize) &&
31
+ !Haml::Util.ap_geq_3?
32
+ Rails.configuration.after_initialize do
33
+ next if defined?(Sass)
34
+ autoload(:Sass, 'sass/rails2_shim')
35
+ # resolve autoload if it looks like they're using Sass without options
36
+ Sass if File.exist?(File.join(RAILS_ROOT, 'public/stylesheets/sass'))
37
+ end
38
+ end
39
+
40
+ # No &method here for Rails 2.1 compatibility
41
+ %w[haml/template].each {|f| require f}
42
+ end
43
+ end
44
+
45
+ require 'haml/util'
46
+ require 'haml/engine'
47
+ require 'haml/railtie'
48
+ require 'haml/haml_ejs'
49
+
@@ -0,0 +1,297 @@
1
+ module Haml
2
+ # This class is used only internally. It holds the buffer of HTML that
3
+ # is eventually output as the resulting document.
4
+ # It's called from within the precompiled code,
5
+ # and helps reduce the amount of processing done within `instance_eval`ed code.
6
+ class Buffer
7
+ include Haml::Helpers
8
+ include Haml::Util
9
+
10
+ # The string that holds the compiled HTML. This is aliased as
11
+ # `_erbout` for compatibility with ERB-specific code.
12
+ #
13
+ # @return [String]
14
+ attr_accessor :buffer
15
+
16
+ # The options hash passed in from {Haml::Engine}.
17
+ #
18
+ # @return [{String => Object}]
19
+ # @see Haml::Engine#options_for_buffer
20
+ attr_accessor :options
21
+
22
+ # The {Buffer} for the enclosing Haml document.
23
+ # This is set for partials and similar sorts of nested templates.
24
+ # It's `nil` at the top level (see \{#toplevel?}).
25
+ #
26
+ # @return [Buffer]
27
+ attr_accessor :upper
28
+
29
+ # nil if there's no capture_haml block running,
30
+ # and the position at which it's beginning the capture if there is one.
31
+ #
32
+ # @return [Fixnum, nil]
33
+ attr_accessor :capture_position
34
+
35
+ # @return [Boolean]
36
+ # @see #active?
37
+ attr_writer :active
38
+
39
+ # @return [Boolean] Whether or not the format is XHTML
40
+ def xhtml?
41
+ not html?
42
+ end
43
+
44
+ # @return [Boolean] Whether or not the format is any flavor of HTML
45
+ def html?
46
+ html4? or html5?
47
+ end
48
+
49
+ # @return [Boolean] Whether or not the format is HTML4
50
+ def html4?
51
+ @options[:format] == :html4
52
+ end
53
+
54
+ # @return [Boolean] Whether or not the format is HTML5.
55
+ def html5?
56
+ @options[:format] == :html5
57
+ end
58
+
59
+ # @return [Boolean] Whether or not this buffer is a top-level template,
60
+ # as opposed to a nested partial
61
+ def toplevel?
62
+ upper.nil?
63
+ end
64
+
65
+ # Whether or not this buffer is currently being used to render a Haml template.
66
+ # Returns `false` if a subtemplate is being rendered,
67
+ # even if it's a subtemplate of this buffer's template.
68
+ #
69
+ # @return [Boolean]
70
+ def active?
71
+ @active
72
+ end
73
+
74
+ # @return [Fixnum] The current indentation level of the document
75
+ def tabulation
76
+ @real_tabs + @tabulation
77
+ end
78
+
79
+ # Sets the current tabulation of the document.
80
+ #
81
+ # @param val [Fixnum] The new tabulation
82
+ def tabulation=(val)
83
+ val = val - @real_tabs
84
+ @tabulation = val > -1 ? val : 0
85
+ end
86
+
87
+ # @param upper [Buffer] The parent buffer
88
+ # @param options [{Symbol => Object}] An options hash.
89
+ # See {Haml::Engine#options\_for\_buffer}
90
+ def initialize(upper = nil, options = {})
91
+ @active = true
92
+ @upper = upper
93
+ @options = options
94
+ @buffer = ruby1_8? ? "" : "".encode(Encoding.find(options[:encoding]))
95
+ @tabulation = 0
96
+
97
+ # The number of tabs that Engine thinks we should have
98
+ # @real_tabs + @tabulation is the number of tabs actually output
99
+ @real_tabs = 0
100
+ end
101
+
102
+ # Appends text to the buffer, properly tabulated.
103
+ # Also modifies the document's indentation.
104
+ #
105
+ # @param text [String] The text to append
106
+ # @param tab_change [Fixnum] The number of tabs by which to increase
107
+ # or decrease the document's indentation
108
+ # @param dont_tab_up [Boolean] If true, don't indent the first line of `text`
109
+ def push_text(text, tab_change, dont_tab_up)
110
+ if @tabulation > 0
111
+ # Have to push every line in by the extra user set tabulation.
112
+ # Don't push lines with just whitespace, though,
113
+ # because that screws up precompiled indentation.
114
+ text.gsub!(/^(?!\s+$)/m, tabs)
115
+ text.sub!(tabs, '') if dont_tab_up
116
+ end
117
+
118
+ @buffer << text
119
+ @real_tabs += tab_change
120
+ end
121
+
122
+ # Modifies the indentation of the document.
123
+ #
124
+ # @param tab_change [Fixnum] The number of tabs by which to increase
125
+ # or decrease the document's indentation
126
+ def adjust_tabs(tab_change)
127
+ @real_tabs += tab_change
128
+ end
129
+
130
+ Haml::Util.def_static_method(self, :format_script, [:result],
131
+ :preserve_script, :in_tag, :preserve_tag, :escape_html,
132
+ :nuke_inner_whitespace, :interpolated, :ugly, <<RUBY)
133
+ <% # Escape HTML here so that the safety of the string is preserved in Rails
134
+ result_name = escape_html ? "html_escape(result.to_s)" : "result.to_s" %>
135
+ <% unless ugly %>
136
+ # If we're interpolated,
137
+ # then the custom tabulation is handled in #push_text.
138
+ # The easiest way to avoid it here is to reset @tabulation.
139
+ <% if interpolated %>
140
+ old_tabulation = @tabulation
141
+ @tabulation = 0
142
+ <% end %>
143
+
144
+ tabulation = @real_tabs
145
+ result = <%= result_name %>.<% if nuke_inner_whitespace %>strip<% else %>rstrip<% end %>
146
+ <% else %>
147
+ result = <%= result_name %><% if nuke_inner_whitespace %>.strip<% end %>
148
+ <% end %>
149
+
150
+ <% if preserve_tag %>
151
+ result = Haml::Helpers.preserve(result)
152
+ <% elsif preserve_script %>
153
+ result = Haml::Helpers.find_and_preserve(result, options[:preserve])
154
+ <% end %>
155
+
156
+ <% if ugly %>
157
+ return result
158
+ <% else %>
159
+
160
+ has_newline = result.include?("\\n")
161
+ <% if in_tag && !nuke_inner_whitespace %>
162
+ <% unless preserve_tag %> if !has_newline <% end %>
163
+ @real_tabs -= 1
164
+ <% if interpolated %> @tabulation = old_tabulation <% end %>
165
+ return result
166
+ <% unless preserve_tag %> end <% end %>
167
+ <% end %>
168
+
169
+ # Precompiled tabulation may be wrong
170
+ <% if !interpolated && !in_tag %>
171
+ result = tabs + result if @tabulation > 0
172
+ <% end %>
173
+
174
+ if has_newline
175
+ result = result.gsub "\\n", "\\n" + tabs(tabulation)
176
+
177
+ # Add tabulation if it wasn't precompiled
178
+ <% if in_tag && !nuke_inner_whitespace %> result = tabs(tabulation) + result <% end %>
179
+ end
180
+
181
+ <% if in_tag && !nuke_inner_whitespace %>
182
+ result = "\\n\#{result}\\n\#{tabs(tabulation-1)}"
183
+ @real_tabs -= 1
184
+ <% end %>
185
+ <% if interpolated %> @tabulation = old_tabulation <% end %>
186
+ result
187
+ <% end %>
188
+ RUBY
189
+
190
+ def attributes(class_id, obj_ref, *attributes_hashes)
191
+ attributes = class_id
192
+ attributes_hashes.each do |old|
193
+ self.class.merge_attrs(attributes, to_hash(old.map {|k, v| [k.to_s, v]}))
194
+ end
195
+ self.class.merge_attrs(attributes, parse_object_ref(obj_ref)) if obj_ref
196
+ Compiler.build_attributes(
197
+ html?, @options[:attr_wrapper], @options[:escape_attrs], attributes)
198
+ end
199
+
200
+ # Remove the whitespace from the right side of the buffer string.
201
+ # Doesn't do anything if we're at the beginning of a capture_haml block.
202
+ def rstrip!
203
+ if capture_position.nil?
204
+ buffer.rstrip!
205
+ return
206
+ end
207
+
208
+ buffer << buffer.slice!(capture_position..-1).rstrip
209
+ end
210
+
211
+ # Merges two attribute hashes.
212
+ # This is the same as `to.merge!(from)`,
213
+ # except that it merges id, class, and data attributes.
214
+ #
215
+ # ids are concatenated with `"_"`,
216
+ # and classes are concatenated with `" "`.
217
+ # data hashes are simply merged.
218
+ #
219
+ # Destructively modifies both `to` and `from`.
220
+ #
221
+ # @param to [{String => String}] The attribute hash to merge into
222
+ # @param from [{String => #to_s}] The attribute hash to merge from
223
+ # @return [{String => String}] `to`, after being merged
224
+ def self.merge_attrs(to, from)
225
+ from['id'] = Compiler.filter_and_join(from['id'], '_') if from['id']
226
+ if to['id'] && from['id']
227
+ to['id'] << '_' << from.delete('id').to_s
228
+ elsif to['id'] || from['id']
229
+ from['id'] ||= to['id']
230
+ end
231
+
232
+ from['class'] = Compiler.filter_and_join(from['class'], ' ') if from['class']
233
+ if to['class'] && from['class']
234
+ # Make sure we don't duplicate class names
235
+ from['class'] = (from['class'].to_s.split(' ') | to['class'].split(' ')).sort.join(' ')
236
+ elsif to['class'] || from['class']
237
+ from['class'] ||= to['class']
238
+ end
239
+
240
+ from_data = from['data'].is_a?(Hash)
241
+ to_data = to['data'].is_a?(Hash)
242
+ if from_data && to_data
243
+ to['data'] = to['data'].merge(from['data'])
244
+ elsif to_data
245
+ to = Haml::Util.map_keys(to.delete('data')) {|name| "data-#{name}"}.merge(to)
246
+ elsif from_data
247
+ from = Haml::Util.map_keys(from.delete('data')) {|name| "data-#{name}"}.merge(from)
248
+ end
249
+
250
+ to.merge!(from)
251
+ end
252
+
253
+ private
254
+
255
+ @@tab_cache = {}
256
+ # Gets `count` tabs. Mostly for internal use.
257
+ def tabs(count = 0)
258
+ tabs = [count + @tabulation, 0].max
259
+ @@tab_cache[tabs] ||= ' ' * tabs
260
+ end
261
+
262
+ # Takes an array of objects and uses the class and id of the first
263
+ # one to create an attributes hash.
264
+ # The second object, if present, is used as a prefix,
265
+ # just like you can do with `dom_id()` and `dom_class()` in Rails
266
+ def parse_object_ref(ref)
267
+ prefix = ref[1]
268
+ ref = ref[0]
269
+ # Let's make sure the value isn't nil. If it is, return the default Hash.
270
+ return {} if ref.nil?
271
+ class_name =
272
+ if ref.respond_to?(:haml_object_ref)
273
+ ref.haml_object_ref
274
+ else
275
+ underscore(ref.class)
276
+ end
277
+ id = "#{class_name}_#{ref.id || 'new'}"
278
+ if prefix
279
+ class_name = "#{ prefix }_#{ class_name}"
280
+ id = "#{ prefix }_#{ id }"
281
+ end
282
+
283
+ {'id' => id, 'class' => class_name}
284
+ end
285
+
286
+ # Changes a word from camel case to underscores.
287
+ # Based on the method of the same name in Rails' Inflector,
288
+ # but copied here so it'll run properly without Rails.
289
+ def underscore(camel_cased_word)
290
+ camel_cased_word.to_s.gsub(/::/, '_').
291
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
292
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
293
+ tr("-", "_").
294
+ downcase
295
+ end
296
+ end
297
+ end
@@ -0,0 +1,486 @@
1
+ require 'cgi'
2
+
3
+ module Haml
4
+ module Compiler
5
+ include Haml::Util
6
+
7
+ private
8
+
9
+ # Returns the precompiled string with the preamble and postamble
10
+ def precompiled_with_ambles(local_names)
11
+ preamble = <<END.gsub("\n", ";")
12
+ begin
13
+ extend Haml::Helpers
14
+ _hamlout = @haml_buffer = Haml::Buffer.new(@haml_buffer, #{options_for_buffer.inspect})
15
+ _erbout = _hamlout.buffer
16
+ __in_erb_template = true
17
+ END
18
+ postamble = <<END.gsub("\n", ";")
19
+ #{precompiled_method_return_value}
20
+ ensure
21
+ @haml_buffer = @haml_buffer.upper
22
+ end
23
+ END
24
+ preamble + locals_code(local_names) + precompiled + postamble
25
+ end
26
+
27
+ # Returns the string used as the return value of the precompiled method.
28
+ # This method exists so it can be monkeypatched to return modified values.
29
+ def precompiled_method_return_value
30
+ "_erbout"
31
+ end
32
+
33
+ def locals_code(names)
34
+ names = names.keys if Hash == names
35
+
36
+ names.map do |name|
37
+ # Can't use || because someone might explicitly pass in false with a symbol
38
+ sym_local = "_haml_locals[#{inspect_obj(name.to_sym)}]"
39
+ str_local = "_haml_locals[#{inspect_obj(name.to_s)}]"
40
+ "#{name} = #{sym_local}.nil? ? #{str_local} : #{sym_local}"
41
+ end.join(';') + ';'
42
+ end
43
+
44
+ def compile_root
45
+ @dont_indent_next_line = @dont_tab_up_next_text = false
46
+ @output_line = 1
47
+ @indentation = nil
48
+ yield
49
+ flush_merged_text
50
+ end
51
+
52
+ def compile_plain
53
+ push_text @node.value[:text]
54
+ end
55
+
56
+ def compile_script(&block)
57
+ push_script(@node.value[:text],
58
+ :preserve_script => @node.value[:preserve],
59
+ :escape_html => @node.value[:escape_html], &block)
60
+ end
61
+
62
+ def compile_silent_script
63
+ return if @options[:suppress_eval]
64
+ push_silent(@node.value[:text])
65
+ keyword = @node.value[:keyword]
66
+ ruby_block = block_given? && !keyword
67
+
68
+ if block_given?
69
+ # Store these values because for conditional statements,
70
+ # we want to restore them for each branch
71
+ @node.value[:dont_indent_next_line] = @dont_indent_next_line
72
+ @node.value[:dont_tab_up_next_text] = @dont_tab_up_next_text
73
+ yield
74
+ push_silent("end", :can_suppress) unless @node.value[:dont_push_end]
75
+ elsif keyword == "end"
76
+ if @node.parent.children.last.equal?(@node)
77
+ # Since this "end" is ending the block,
78
+ # we don't need to generate an additional one
79
+ @node.parent.value[:dont_push_end] = true
80
+ end
81
+ # Don't restore dont_* for end because it isn't a conditional branch.
82
+ elsif Parser::MID_BLOCK_KEYWORDS.include?(keyword)
83
+ # Restore dont_* for this conditional branch
84
+ @dont_indent_next_line = @node.parent.value[:dont_indent_next_line]
85
+ @dont_tab_up_next_text = @node.parent.value[:dont_tab_up_next_text]
86
+ end
87
+ end
88
+
89
+ def compile_haml_comment; end
90
+
91
+ def compile_tag
92
+ t = @node.value
93
+
94
+ # Get rid of whitespace outside of the tag if we need to
95
+ rstrip_buffer! if t[:nuke_outer_whitespace]
96
+
97
+ dont_indent_next_line =
98
+ (t[:nuke_outer_whitespace] && !block_given?) ||
99
+ (t[:nuke_inner_whitespace] && block_given?)
100
+
101
+ if @options[:suppress_eval]
102
+ object_ref = "nil"
103
+ parse = false
104
+ value = t[:parse] ? nil : t[:value]
105
+ attributes_hashes = {}
106
+ preserve_script = false
107
+ else
108
+ object_ref = t[:object_ref]
109
+ parse = t[:parse]
110
+ value = t[:value]
111
+ attributes_hashes = t[:attributes_hashes]
112
+ preserve_script = t[:preserve_script]
113
+ end
114
+
115
+ # Check if we can render the tag directly to text and not process it in the buffer
116
+ if object_ref == "nil" && attributes_hashes.empty? && !preserve_script
117
+ tag_closed = !block_given? && !t[:self_closing] && !parse
118
+
119
+ open_tag = prerender_tag(t[:name], t[:self_closing], t[:attributes])
120
+ if tag_closed
121
+ open_tag << "#{value}</#{t[:name]}>"
122
+ open_tag << "\n" unless t[:nuke_outer_whitespace]
123
+ elsif !(parse || t[:nuke_inner_whitespace] ||
124
+ (t[:self_closing] && t[:nuke_outer_whitespace]))
125
+ open_tag << "\n"
126
+ end
127
+
128
+ push_merged_text(open_tag,
129
+ tag_closed || t[:self_closing] || t[:nuke_inner_whitespace] ? 0 : 1,
130
+ !t[:nuke_outer_whitespace])
131
+
132
+ @dont_indent_next_line = dont_indent_next_line
133
+ return if tag_closed
134
+ else
135
+ if attributes_hashes.empty?
136
+ attributes_hashes = ''
137
+ elsif attributes_hashes.size == 1
138
+ attributes_hashes = ", #{attributes_hashes.first}"
139
+ else
140
+ attributes_hashes = ", (#{attributes_hashes.join(").merge(")})"
141
+ end
142
+
143
+ push_merged_text "<#{t[:name]}", 0, !t[:nuke_outer_whitespace]
144
+ push_generated_script(
145
+ "_hamlout.attributes(#{inspect_obj(t[:attributes])}, #{object_ref}#{attributes_hashes})")
146
+ concat_merged_text(
147
+ if t[:self_closing] && xhtml?
148
+ " />" + (t[:nuke_outer_whitespace] ? "" : "\n")
149
+ else
150
+ ">" + ((if t[:self_closing] && html?
151
+ t[:nuke_outer_whitespace]
152
+ else
153
+ !block_given? || t[:preserve_tag] || t[:nuke_inner_whitespace]
154
+ end) ? "" : "\n")
155
+ end)
156
+
157
+ if value && !parse
158
+ concat_merged_text("#{value}</#{t[:name]}>#{t[:nuke_outer_whitespace] ? "" : "\n"}")
159
+ else
160
+ @to_merge << [:text, '', 1] unless t[:nuke_inner_whitespace]
161
+ end
162
+
163
+ @dont_indent_next_line = dont_indent_next_line
164
+ end
165
+
166
+ return if t[:self_closing]
167
+
168
+ if value.nil?
169
+ @output_tabs += 1 unless t[:nuke_inner_whitespace]
170
+ yield if block_given?
171
+ @output_tabs -= 1 unless t[:nuke_inner_whitespace]
172
+ rstrip_buffer! if t[:nuke_inner_whitespace]
173
+ push_merged_text("</#{t[:name]}>" + (t[:nuke_outer_whitespace] ? "" : "\n"),
174
+ t[:nuke_inner_whitespace] ? 0 : -1, !t[:nuke_inner_whitespace])
175
+ @dont_indent_next_line = t[:nuke_outer_whitespace]
176
+ return
177
+ end
178
+
179
+ if parse
180
+ push_script(value, t.merge(:in_tag => true))
181
+ concat_merged_text("</#{t[:name]}>" + (t[:nuke_outer_whitespace] ? "" : "\n"))
182
+ end
183
+ end
184
+
185
+ def compile_comment
186
+ open = "<!--#{@node.value[:conditional]}"
187
+
188
+ # Render it statically if possible
189
+ unless block_given?
190
+ push_text("#{open} #{@node.value[:text]} #{@node.value[:conditional] ? "<![endif]-->" : "-->"}")
191
+ return
192
+ end
193
+
194
+ push_text(open, 1)
195
+ @output_tabs += 1
196
+ yield if block_given?
197
+ @output_tabs -= 1
198
+ push_text(@node.value[:conditional] ? "<![endif]-->" : "-->", -1)
199
+ end
200
+
201
+ def compile_doctype
202
+ doctype = text_for_doctype
203
+ push_text doctype if doctype
204
+ end
205
+
206
+ def compile_filter
207
+ unless filter = Filters.defined[@node.value[:name]]
208
+ raise Error.new("Filter \"#{@node.value[:name]}\" is not defined.", @node.line - 1)
209
+ end
210
+ filter.internal_compile(self, @node.value[:text])
211
+ end
212
+
213
+ def compile_ejs_interpolate
214
+ push_text("#{HamlEjs.open_interpolate}#{@node.value[:text]}#{HamlEjs.close_interpolate}")
215
+ end
216
+
217
+ def compile_ejs_conditional
218
+ if @node.value[:else]
219
+ @output_tabs -= 1
220
+ if @node.value[:expression]
221
+ push_text("#{HamlEjs.open_evaluate}}else if(#{@node.value[:expression]}){#{HamlEjs.close_evaluate}", 1)
222
+ else
223
+ push_text("#{HamlEjs.open_evaluate}}else{#{HamlEjs.close_evaluate}", 1)
224
+ end
225
+ else
226
+ negate = @node.value[:negate] ? '!' : ''
227
+ push_text("#{HamlEjs.open_evaluate}if(#{negate}#{@node.value[:expression]}){#{HamlEjs.close_evaluate}", 1)
228
+ @output_tabs += 1
229
+ end
230
+ yield if block_given?
231
+ if @node.value[:else]
232
+ @output_tabs += 1
233
+ else
234
+ @output_tabs -= 1
235
+ push_text("#{HamlEjs.open_evaluate}}#{HamlEjs.close_evaluate}", -1)
236
+ end
237
+ end
238
+
239
+ def compile_ejs_iterate
240
+ push_text("#{HamlEjs.open_evaluate}#{HamlEjs.iterate}(#{@node.value[:collection]},function(collectionIndex,collectionElement){with(collectionElement){#{HamlEjs.close_evaluate}", 1)
241
+ @output_tabs += 1
242
+ yield if block_given?
243
+ @output_tabs -= 1
244
+ push_text("#{HamlEjs.open_evaluate}}});#{HamlEjs.close_evaluate}", -1)
245
+ end
246
+
247
+ def text_for_doctype
248
+ if @node.value[:type] == "xml"
249
+ return nil if html?
250
+ wrapper = @options[:attr_wrapper]
251
+ return "<?xml version=#{wrapper}1.0#{wrapper} encoding=#{wrapper}#{@node.value[:encoding] || "utf-8"}#{wrapper} ?>"
252
+ end
253
+
254
+ if html5?
255
+ '<!DOCTYPE html>'
256
+ else
257
+ if xhtml?
258
+ if @node.value[:version] == "1.1"
259
+ '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">'
260
+ elsif @node.value[:version] == "5"
261
+ '<!DOCTYPE html>'
262
+ else
263
+ case @node.value[:type]
264
+ when "strict"; '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
265
+ when "frameset"; '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">'
266
+ when "mobile"; '<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">'
267
+ when "rdfa"; '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">'
268
+ when "basic"; '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">'
269
+ else '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
270
+ end
271
+ end
272
+
273
+ elsif html4?
274
+ case @node.value[:type]
275
+ when "strict"; '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">'
276
+ when "frameset"; '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">'
277
+ else '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">'
278
+ end
279
+ end
280
+ end
281
+ end
282
+
283
+ # Evaluates `text` in the context of the scope object, but
284
+ # does not output the result.
285
+ def push_silent(text, can_suppress = false)
286
+ flush_merged_text
287
+ return if can_suppress && options[:suppress_eval]
288
+ @precompiled << "#{resolve_newlines}#{text}\n"
289
+ @output_line += text.count("\n") + 1
290
+ end
291
+
292
+ # Adds `text` to `@buffer` with appropriate tabulation
293
+ # without parsing it.
294
+ def push_merged_text(text, tab_change = 0, indent = true)
295
+ text = !indent || @dont_indent_next_line || @options[:ugly] ? text : "#{' ' * @output_tabs}#{text}"
296
+ @to_merge << [:text, text, tab_change]
297
+ @dont_indent_next_line = false
298
+ end
299
+
300
+ # Concatenate `text` to `@buffer` without tabulation.
301
+ def concat_merged_text(text)
302
+ @to_merge << [:text, text, 0]
303
+ end
304
+
305
+ def push_text(text, tab_change = 0)
306
+ push_merged_text("#{text}\n", tab_change)
307
+ end
308
+
309
+ def flush_merged_text
310
+ return if @to_merge.empty?
311
+
312
+ str = ""
313
+ mtabs = 0
314
+ @to_merge.each do |type, val, tabs|
315
+ case type
316
+ when :text
317
+ str << inspect_obj(val)[1...-1]
318
+ mtabs += tabs
319
+ when :script
320
+ if mtabs != 0 && !@options[:ugly]
321
+ val = "_hamlout.adjust_tabs(#{mtabs}); " + val
322
+ end
323
+ str << "\#{#{val}}"
324
+ mtabs = 0
325
+ else
326
+ raise SyntaxError.new("[HAML BUG] Undefined entry in Haml::Compiler@to_merge.")
327
+ end
328
+ end
329
+
330
+ unless str.empty?
331
+ @precompiled <<
332
+ if @options[:ugly]
333
+ "_hamlout.buffer << \"#{str}\";"
334
+ else
335
+ "_hamlout.push_text(\"#{str}\", #{mtabs}, #{@dont_tab_up_next_text.inspect});"
336
+ end
337
+ end
338
+ @to_merge = []
339
+ @dont_tab_up_next_text = false
340
+ end
341
+
342
+ # Causes `text` to be evaluated in the context of
343
+ # the scope object and the result to be added to `@buffer`.
344
+ #
345
+ # If `opts[:preserve_script]` is true, Haml::Helpers#find_and_flatten is run on
346
+ # the result before it is added to `@buffer`
347
+ def push_script(text, opts = {})
348
+ return if options[:suppress_eval]
349
+
350
+ args = %w[preserve_script in_tag preserve_tag escape_html nuke_inner_whitespace]
351
+ args.map! {|name| opts[name.to_sym]}
352
+ args << !block_given? << @options[:ugly]
353
+
354
+ no_format = @options[:ugly] &&
355
+ !(opts[:preserve_script] || opts[:preserve_tag] || opts[:escape_html])
356
+ output_expr = "(#{text}\n)"
357
+ static_method = "_hamlout.#{static_method_name(:format_script, *args)}"
358
+
359
+ # Prerender tabulation unless we're in a tag
360
+ push_merged_text '' unless opts[:in_tag]
361
+
362
+ unless block_given?
363
+ push_generated_script(no_format ? "#{text}\n" : "#{static_method}(#{output_expr});")
364
+ concat_merged_text("\n") unless opts[:in_tag] || opts[:nuke_inner_whitespace]
365
+ return
366
+ end
367
+
368
+ flush_merged_text
369
+ push_silent "haml_temp = #{text}"
370
+ yield
371
+ push_silent('end', :can_suppress) unless @node.value[:dont_push_end]
372
+ @precompiled << "_hamlout.buffer << #{no_format ? "haml_temp.to_s;" : "#{static_method}(haml_temp);"}"
373
+ concat_merged_text("\n") unless opts[:in_tag] || opts[:nuke_inner_whitespace] || @options[:ugly]
374
+ end
375
+
376
+ def push_generated_script(text)
377
+ @to_merge << [:script, resolve_newlines + text]
378
+ @output_line += text.count("\n")
379
+ end
380
+
381
+ # This is a class method so it can be accessed from Buffer.
382
+ def self.build_attributes(is_html, attr_wrapper, escape_attrs, attributes = {})
383
+ quote_escape = attr_wrapper == '"' ? "&quot;" : "&apos;"
384
+ other_quote_char = attr_wrapper == '"' ? "'" : '"'
385
+
386
+ if attributes['data'].is_a?(Hash)
387
+ attributes = attributes.dup
388
+ attributes =
389
+ Haml::Util.map_keys(attributes.delete('data')) {|name| "data-#{name}"}.merge(attributes)
390
+ end
391
+
392
+ result = attributes.collect do |attr, value|
393
+ next if value.nil?
394
+
395
+ value = filter_and_join(value, ' ') if attr == 'class'
396
+ value = filter_and_join(value, '_') if attr == 'id'
397
+
398
+ if value == true
399
+ next " #{attr}" if is_html
400
+ next " #{attr}=#{attr_wrapper}#{attr}#{attr_wrapper}"
401
+ elsif value == false
402
+ next
403
+ end
404
+
405
+ escaped =
406
+ if escape_attrs == :once
407
+ Haml::Helpers.escape_once(value.to_s)
408
+ elsif escape_attrs
409
+ CGI.escapeHTML(value.to_s)
410
+ else
411
+ value.to_s
412
+ end
413
+ value = Haml::Helpers.preserve(escaped)
414
+ if escape_attrs
415
+ # We want to decide whether or not to escape quotes
416
+ value = value.gsub('&quot;', '"')
417
+ this_attr_wrapper = attr_wrapper
418
+ if value.include? attr_wrapper
419
+ if value.include? other_quote_char
420
+ value = value.gsub(attr_wrapper, quote_escape)
421
+ else
422
+ this_attr_wrapper = other_quote_char
423
+ end
424
+ end
425
+ else
426
+ this_attr_wrapper = attr_wrapper
427
+ end
428
+ " #{attr}=#{this_attr_wrapper}#{value}#{this_attr_wrapper}"
429
+ end
430
+ result.compact.sort.join
431
+ end
432
+
433
+ def self.filter_and_join(value, separator)
434
+ return "" if value == ""
435
+ value = [value] unless value.is_a?(Array)
436
+ value = value.flatten.collect {|item| item ? item.to_s : nil}.compact.join(separator)
437
+ return !value.empty? && value
438
+ end
439
+
440
+ def prerender_tag(name, self_close, attributes)
441
+ attributes_string = Compiler.build_attributes(
442
+ html?, @options[:attr_wrapper], @options[:escape_attrs], attributes)
443
+ "<#{name}#{attributes_string}#{self_close && xhtml? ? ' /' : ''}>"
444
+ end
445
+
446
+ def resolve_newlines
447
+ diff = @node.line - @output_line
448
+ return "" if diff <= 0
449
+ @output_line = @node.line
450
+ "\n" * [diff, 0].max
451
+ end
452
+
453
+ # Get rid of and whitespace at the end of the buffer
454
+ # or the merged text
455
+ def rstrip_buffer!(index = -1)
456
+ last = @to_merge[index]
457
+ if last.nil?
458
+ push_silent("_hamlout.rstrip!", false)
459
+ @dont_tab_up_next_text = true
460
+ return
461
+ end
462
+
463
+ case last.first
464
+ when :text
465
+ last[1].rstrip!
466
+ if last[1].empty?
467
+ @to_merge.slice! index
468
+ rstrip_buffer! index
469
+ end
470
+ when :script
471
+ last[1].gsub!(/\(haml_temp, (.*?)\);$/, '(haml_temp.rstrip, \1);')
472
+ rstrip_buffer! index - 1
473
+ else
474
+ raise SyntaxError.new("[HAML BUG] Undefined entry in Haml::Compiler@to_merge.")
475
+ end
476
+ end
477
+
478
+ def compile(node)
479
+ parent, @node = @node, node
480
+ block = proc {node.children.each {|c| compile c}}
481
+ send("compile_#{node.type}", &(block unless node.children.empty?))
482
+ ensure
483
+ @node = parent
484
+ end
485
+ end
486
+ end