haml 3.0.25 → 3.1.0.alpha.2
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.
- data/.yardopts +1 -1
- data/CONTRIBUTING +0 -1
- data/EDGE_GEM_VERSION +1 -0
- data/MIT-LICENSE +1 -1
- data/README.md +10 -175
- data/Rakefile +56 -84
- data/VERSION +1 -1
- data/VERSION_NAME +1 -1
- data/init.rb +1 -1
- data/lib/haml.rb +14 -12
- data/lib/haml/engine.rb +1 -1
- data/lib/haml/exec.rb +19 -316
- data/lib/haml/helpers/action_view_extensions.rb +1 -1
- data/lib/haml/html.rb +69 -76
- data/lib/haml/precompiler.rb +34 -41
- data/lib/haml/railtie.rb +4 -6
- data/lib/haml/template/plugin.rb +6 -16
- data/lib/haml/util.rb +91 -107
- data/lib/haml/version.rb +7 -0
- data/test/benchmark.rb +2 -9
- data/test/haml/engine_test.rb +195 -92
- data/test/haml/html2haml/erb_tests.rb +0 -14
- data/test/haml/util_test.rb +32 -0
- data/test/test_helper.rb +0 -39
- metadata +96 -324
- data/bin/css2sass +0 -13
- data/bin/sass +0 -8
- data/bin/sass-convert +0 -7
- data/extra/haml-mode.el +0 -753
- data/extra/sass-mode.el +0 -207
- data/lib/haml/util/subset_map.rb +0 -101
- data/lib/sass.rb +0 -29
- data/lib/sass/callbacks.rb +0 -52
- data/lib/sass/css.rb +0 -294
- data/lib/sass/engine.rb +0 -720
- data/lib/sass/environment.rb +0 -143
- data/lib/sass/error.rb +0 -198
- data/lib/sass/files.rb +0 -160
- data/lib/sass/less.rb +0 -382
- data/lib/sass/plugin.rb +0 -279
- data/lib/sass/plugin/configuration.rb +0 -221
- data/lib/sass/plugin/generic.rb +0 -15
- data/lib/sass/plugin/merb.rb +0 -37
- data/lib/sass/plugin/rack.rb +0 -47
- data/lib/sass/plugin/rails.rb +0 -32
- data/lib/sass/plugin/staleness_checker.rb +0 -123
- data/lib/sass/repl.rb +0 -58
- data/lib/sass/script.rb +0 -63
- data/lib/sass/script/bool.rb +0 -18
- data/lib/sass/script/color.rb +0 -491
- data/lib/sass/script/css_lexer.rb +0 -29
- data/lib/sass/script/css_parser.rb +0 -31
- data/lib/sass/script/funcall.rb +0 -77
- data/lib/sass/script/functions.rb +0 -861
- data/lib/sass/script/interpolation.rb +0 -70
- data/lib/sass/script/lexer.rb +0 -337
- data/lib/sass/script/literal.rb +0 -236
- data/lib/sass/script/node.rb +0 -112
- data/lib/sass/script/number.rb +0 -423
- data/lib/sass/script/operation.rb +0 -95
- data/lib/sass/script/parser.rb +0 -401
- data/lib/sass/script/string.rb +0 -67
- data/lib/sass/script/string_interpolation.rb +0 -93
- data/lib/sass/script/unary_operation.rb +0 -57
- data/lib/sass/script/variable.rb +0 -48
- data/lib/sass/scss.rb +0 -17
- data/lib/sass/scss/css_parser.rb +0 -46
- data/lib/sass/scss/parser.rb +0 -855
- data/lib/sass/scss/rx.rb +0 -126
- data/lib/sass/scss/sass_parser.rb +0 -11
- data/lib/sass/scss/script_lexer.rb +0 -15
- data/lib/sass/scss/script_parser.rb +0 -25
- data/lib/sass/scss/static_parser.rb +0 -40
- data/lib/sass/selector.rb +0 -361
- data/lib/sass/selector/abstract_sequence.rb +0 -62
- data/lib/sass/selector/comma_sequence.rb +0 -82
- data/lib/sass/selector/sequence.rb +0 -237
- data/lib/sass/selector/simple.rb +0 -113
- data/lib/sass/selector/simple_sequence.rb +0 -136
- data/lib/sass/tree/charset_node.rb +0 -37
- data/lib/sass/tree/comment_node.rb +0 -128
- data/lib/sass/tree/debug_node.rb +0 -36
- data/lib/sass/tree/directive_node.rb +0 -75
- data/lib/sass/tree/extend_node.rb +0 -65
- data/lib/sass/tree/for_node.rb +0 -55
- data/lib/sass/tree/if_node.rb +0 -69
- data/lib/sass/tree/import_node.rb +0 -102
- data/lib/sass/tree/mixin_def_node.rb +0 -48
- data/lib/sass/tree/mixin_node.rb +0 -111
- data/lib/sass/tree/node.rb +0 -464
- data/lib/sass/tree/prop_node.rb +0 -220
- data/lib/sass/tree/root_node.rb +0 -163
- data/lib/sass/tree/rule_node.rb +0 -261
- data/lib/sass/tree/variable_node.rb +0 -39
- data/lib/sass/tree/warn_node.rb +0 -42
- data/lib/sass/tree/while_node.rb +0 -36
- data/test/haml/util/subset_map_test.rb +0 -91
- data/test/sass/callbacks_test.rb +0 -61
- data/test/sass/conversion_test.rb +0 -1218
- data/test/sass/css2sass_test.rb +0 -364
- data/test/sass/data/hsl-rgb.txt +0 -319
- data/test/sass/engine_test.rb +0 -2267
- data/test/sass/extend_test.rb +0 -1348
- data/test/sass/functions_test.rb +0 -556
- data/test/sass/less_conversion_test.rb +0 -653
- data/test/sass/more_results/more1.css +0 -9
- data/test/sass/more_results/more1_with_line_comments.css +0 -26
- data/test/sass/more_results/more_import.css +0 -29
- data/test/sass/more_templates/_more_partial.sass +0 -2
- data/test/sass/more_templates/more1.sass +0 -23
- data/test/sass/more_templates/more_import.sass +0 -11
- data/test/sass/plugin_test.rb +0 -433
- data/test/sass/results/alt.css +0 -4
- data/test/sass/results/basic.css +0 -9
- data/test/sass/results/compact.css +0 -5
- data/test/sass/results/complex.css +0 -86
- data/test/sass/results/compressed.css +0 -1
- data/test/sass/results/expanded.css +0 -19
- data/test/sass/results/import.css +0 -31
- data/test/sass/results/import_charset.css +0 -4
- data/test/sass/results/import_charset_1_8.css +0 -4
- data/test/sass/results/import_charset_ibm866.css +0 -4
- data/test/sass/results/line_numbers.css +0 -49
- data/test/sass/results/mixins.css +0 -95
- data/test/sass/results/multiline.css +0 -24
- data/test/sass/results/nested.css +0 -22
- data/test/sass/results/options.css +0 -1
- data/test/sass/results/parent_ref.css +0 -13
- data/test/sass/results/script.css +0 -16
- data/test/sass/results/scss_import.css +0 -31
- data/test/sass/results/scss_importee.css +0 -2
- data/test/sass/results/subdir/nested_subdir/nested_subdir.css +0 -1
- data/test/sass/results/subdir/subdir.css +0 -3
- data/test/sass/results/units.css +0 -11
- data/test/sass/results/warn.css +0 -0
- data/test/sass/results/warn_imported.css +0 -0
- data/test/sass/script_conversion_test.rb +0 -314
- data/test/sass/script_test.rb +0 -470
- data/test/sass/scss/css_test.rb +0 -916
- data/test/sass/scss/rx_test.rb +0 -156
- data/test/sass/scss/scss_test.rb +0 -1122
- data/test/sass/scss/test_helper.rb +0 -37
- data/test/sass/templates/_imported_charset_ibm866.sass +0 -4
- data/test/sass/templates/_imported_charset_utf8.sass +0 -4
- data/test/sass/templates/_partial.sass +0 -2
- data/test/sass/templates/alt.sass +0 -16
- data/test/sass/templates/basic.sass +0 -23
- data/test/sass/templates/bork1.sass +0 -2
- data/test/sass/templates/bork2.sass +0 -2
- data/test/sass/templates/bork3.sass +0 -2
- data/test/sass/templates/bork4.sass +0 -2
- data/test/sass/templates/compact.sass +0 -17
- data/test/sass/templates/complex.sass +0 -305
- data/test/sass/templates/compressed.sass +0 -15
- data/test/sass/templates/expanded.sass +0 -17
- data/test/sass/templates/import.sass +0 -12
- data/test/sass/templates/import_charset.sass +0 -7
- data/test/sass/templates/import_charset_1_8.sass +0 -4
- data/test/sass/templates/import_charset_ibm866.sass +0 -9
- data/test/sass/templates/importee.less +0 -2
- data/test/sass/templates/importee.sass +0 -19
- data/test/sass/templates/line_numbers.sass +0 -13
- data/test/sass/templates/mixin_bork.sass +0 -5
- data/test/sass/templates/mixins.sass +0 -76
- data/test/sass/templates/multiline.sass +0 -20
- data/test/sass/templates/nested.sass +0 -25
- data/test/sass/templates/nested_bork1.sass +0 -2
- data/test/sass/templates/nested_bork2.sass +0 -2
- data/test/sass/templates/nested_bork3.sass +0 -2
- data/test/sass/templates/nested_bork4.sass +0 -2
- data/test/sass/templates/nested_mixin_bork.sass +0 -6
- data/test/sass/templates/options.sass +0 -2
- data/test/sass/templates/parent_ref.sass +0 -25
- data/test/sass/templates/script.sass +0 -101
- data/test/sass/templates/scss_import.scss +0 -11
- data/test/sass/templates/scss_importee.scss +0 -1
- data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +0 -2
- data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +0 -3
- data/test/sass/templates/subdir/subdir.sass +0 -6
- data/test/sass/templates/units.sass +0 -11
- data/test/sass/templates/warn.sass +0 -3
- data/test/sass/templates/warn_imported.sass +0 -4
- data/vendor/fssm/LICENSE +0 -20
- data/vendor/fssm/README.markdown +0 -55
- data/vendor/fssm/Rakefile +0 -59
- data/vendor/fssm/VERSION.yml +0 -5
- data/vendor/fssm/example.rb +0 -9
- data/vendor/fssm/fssm.gemspec +0 -77
- data/vendor/fssm/lib/fssm.rb +0 -33
- data/vendor/fssm/lib/fssm/backends/fsevents.rb +0 -36
- data/vendor/fssm/lib/fssm/backends/inotify.rb +0 -26
- data/vendor/fssm/lib/fssm/backends/polling.rb +0 -25
- data/vendor/fssm/lib/fssm/backends/rubycocoa/fsevents.rb +0 -131
- data/vendor/fssm/lib/fssm/monitor.rb +0 -26
- data/vendor/fssm/lib/fssm/path.rb +0 -91
- data/vendor/fssm/lib/fssm/pathname.rb +0 -502
- data/vendor/fssm/lib/fssm/state/directory.rb +0 -57
- data/vendor/fssm/lib/fssm/state/file.rb +0 -24
- data/vendor/fssm/lib/fssm/support.rb +0 -63
- data/vendor/fssm/lib/fssm/tree.rb +0 -176
- data/vendor/fssm/profile/prof-cache.rb +0 -40
- data/vendor/fssm/profile/prof-fssm-pathname.html +0 -1231
- data/vendor/fssm/profile/prof-pathname.rb +0 -68
- data/vendor/fssm/profile/prof-plain-pathname.html +0 -988
- data/vendor/fssm/profile/prof.html +0 -2379
- data/vendor/fssm/spec/path_spec.rb +0 -75
- data/vendor/fssm/spec/root/duck/quack.txt +0 -0
- data/vendor/fssm/spec/root/file.css +0 -0
- data/vendor/fssm/spec/root/file.rb +0 -0
- data/vendor/fssm/spec/root/file.yml +0 -0
- data/vendor/fssm/spec/root/moo/cow.txt +0 -0
- data/vendor/fssm/spec/spec_helper.rb +0 -14
data/lib/haml/html.rb
CHANGED
@@ -3,90 +3,81 @@ require File.dirname(__FILE__) + '/../haml'
|
|
3
3
|
require 'haml/engine'
|
4
4
|
require 'rubygems'
|
5
5
|
require 'cgi'
|
6
|
-
require 'hpricot'
|
7
6
|
|
8
7
|
module Haml
|
9
8
|
class HTML
|
10
9
|
# A module containing utility methods that every Hpricot node
|
11
10
|
# should have.
|
12
11
|
module Node
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
CGI.unescapeHTML(node.inner_text).gsub(/\n\s*/, ' ').strip << '}'
|
37
|
-
|
38
|
-
if node.next_node.is_a?(::Hpricot::Text)
|
39
|
-
node = node.next_node
|
40
|
-
text << uninterp(node.to_s)
|
41
|
-
node.converted_to_haml = true
|
42
|
-
end
|
43
|
-
|
44
|
-
node = node.next_node
|
45
|
-
end
|
46
|
-
return parse_text_with_interpolation(text, tabs)
|
12
|
+
# Whether this node has already been converted to Haml.
|
13
|
+
# Only used for text nodes and elements.
|
14
|
+
#
|
15
|
+
# @return [Boolean]
|
16
|
+
attr_accessor :converted_to_haml
|
17
|
+
|
18
|
+
# Returns the Haml representation of the given node.
|
19
|
+
#
|
20
|
+
# @param tabs [Fixnum] The indentation level of the resulting Haml.
|
21
|
+
# @option options (see Haml::HTML#initialize)
|
22
|
+
def to_haml(tabs, options)
|
23
|
+
return "" if converted_to_haml || to_s.strip.empty?
|
24
|
+
text = uninterp(self.to_s)
|
25
|
+
node = next_node
|
26
|
+
while node.is_a?(::Hpricot::Elem) && node.name == "haml:loud"
|
27
|
+
node.converted_to_haml = true
|
28
|
+
text << '#{' <<
|
29
|
+
CGI.unescapeHTML(node.inner_text).gsub(/\n\s*/, ' ').strip << '}'
|
30
|
+
|
31
|
+
if node.next_node.is_a?(::Hpricot::Text)
|
32
|
+
node = node.next_node
|
33
|
+
text << uninterp(node.to_s)
|
34
|
+
node.converted_to_haml = true
|
47
35
|
end
|
48
36
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
text = CGI.escapeHTML(uninterp(text))
|
54
|
-
%w[<haml:loud> </haml:loud>].each {|str| text.gsub!(CGI.escapeHTML(str), str)}
|
55
|
-
::Hpricot::XML(text).children.inject("") do |str, elem|
|
56
|
-
if elem.is_a?(::Hpricot::Text)
|
57
|
-
str + CGI.unescapeHTML(elem.to_s)
|
58
|
-
else # <haml:loud> element
|
59
|
-
str + '#{' + CGI.unescapeHTML(elem.innerText.strip) + '}'
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
37
|
+
node = node.next_node
|
38
|
+
end
|
39
|
+
return parse_text_with_interpolation(text, tabs)
|
40
|
+
end
|
63
41
|
|
64
|
-
|
65
|
-
' ' * tabs
|
66
|
-
end
|
42
|
+
private
|
67
43
|
|
68
|
-
|
69
|
-
|
44
|
+
def erb_to_interpolation(text, options)
|
45
|
+
return text unless options[:erb]
|
46
|
+
text = CGI.escapeHTML(uninterp(text))
|
47
|
+
%w[<haml:loud> </haml:loud>].each {|str| text.gsub!(CGI.escapeHTML(str), str)}
|
48
|
+
::Hpricot::XML(text).children.inject("") do |str, elem|
|
49
|
+
if elem.is_a?(::Hpricot::Text)
|
50
|
+
str + CGI.unescapeHTML(elem.to_s)
|
51
|
+
else # <haml:loud> element
|
52
|
+
str + '#{' + CGI.unescapeHTML(elem.innerText.strip) + '}'
|
70
53
|
end
|
54
|
+
end
|
55
|
+
end
|
71
56
|
|
72
|
-
|
73
|
-
|
74
|
-
|
57
|
+
def tabulate(tabs)
|
58
|
+
' ' * tabs
|
59
|
+
end
|
75
60
|
|
76
|
-
|
77
|
-
|
78
|
-
|
61
|
+
def uninterp(text)
|
62
|
+
text.gsub('#{', '\#{') #'
|
63
|
+
end
|
79
64
|
|
80
|
-
|
81
|
-
|
82
|
-
|
65
|
+
def attr_hash
|
66
|
+
attributes.to_hash
|
67
|
+
end
|
83
68
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
69
|
+
def parse_text(text, tabs)
|
70
|
+
parse_text_with_interpolation(uninterp(text), tabs)
|
71
|
+
end
|
72
|
+
|
73
|
+
def parse_text_with_interpolation(text, tabs)
|
74
|
+
text.strip!
|
75
|
+
return "" if text.empty?
|
76
|
+
|
77
|
+
text.split("\n").map do |line|
|
78
|
+
line.strip!
|
79
|
+
"#{tabulate(tabs)}#{'\\' if Haml::Engine::SPECIAL_CHARACTERS.include?(line[0])}#{line}\n"
|
80
|
+
end.join
|
90
81
|
end
|
91
82
|
end
|
92
83
|
end
|
@@ -107,16 +98,11 @@ module Hpricot
|
|
107
98
|
end
|
108
99
|
end
|
109
100
|
|
101
|
+
require 'hpricot'
|
102
|
+
|
110
103
|
# @private
|
111
104
|
HAML_TAGS = %w[haml:block haml:loud haml:silent]
|
112
105
|
|
113
|
-
HAML_TAGS.each do |t|
|
114
|
-
Hpricot::ElementContent[t] = {}
|
115
|
-
Hpricot::ElementContent.keys.each do |key|
|
116
|
-
Hpricot::ElementContent[t][key.hash] = true
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
106
|
Hpricot::ElementContent.keys.each do |k|
|
121
107
|
HAML_TAGS.each do |el|
|
122
108
|
val = Hpricot::ElementContent[k]
|
@@ -124,6 +110,13 @@ Hpricot::ElementContent.keys.each do |k|
|
|
124
110
|
end
|
125
111
|
end
|
126
112
|
|
113
|
+
HAML_TAGS.each do |t|
|
114
|
+
Hpricot::ElementContent[t] = {}
|
115
|
+
Hpricot::ElementContent.keys.each do |key|
|
116
|
+
Hpricot::ElementContent[t][key.hash] = true
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
127
120
|
module Haml
|
128
121
|
# Converts HTML documents into Haml templates.
|
129
122
|
# Depends on [Hpricot](http://github.com/whymirror/hpricot) for HTML parsing.
|
data/lib/haml/precompiler.rb
CHANGED
@@ -118,8 +118,8 @@ END
|
|
118
118
|
|
119
119
|
names.map do |name|
|
120
120
|
# Can't use || because someone might explicitly pass in false with a symbol
|
121
|
-
sym_local = "_haml_locals[#{
|
122
|
-
str_local = "_haml_locals[#{
|
121
|
+
sym_local = "_haml_locals[#{name.to_sym.inspect}]"
|
122
|
+
str_local = "_haml_locals[#{name.to_s.inspect}]"
|
123
123
|
"#{name} = #{sym_local}.nil? ? #{str_local} : #{sym_local}"
|
124
124
|
end.join(';') + ';'
|
125
125
|
end
|
@@ -320,7 +320,7 @@ END
|
|
320
320
|
@to_merge.each do |type, val, tabs|
|
321
321
|
case type
|
322
322
|
when :text
|
323
|
-
str <<
|
323
|
+
str << val.inspect[1...-1]
|
324
324
|
mtabs += tabs
|
325
325
|
when :script
|
326
326
|
if mtabs != 0 && !@options[:ugly]
|
@@ -336,14 +336,12 @@ END
|
|
336
336
|
end
|
337
337
|
end
|
338
338
|
|
339
|
-
|
340
|
-
@
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
end
|
346
|
-
end
|
339
|
+
@precompiled <<
|
340
|
+
if @options[:ugly]
|
341
|
+
"_hamlout.buffer << \"#{str}\";"
|
342
|
+
else
|
343
|
+
"_hamlout.push_text(\"#{str}\", #{mtabs}, #{@dont_tab_up_next_text.inspect});"
|
344
|
+
end
|
347
345
|
@precompiled << "\n" * newlines
|
348
346
|
@to_merge = []
|
349
347
|
@dont_tab_up_next_text = false
|
@@ -579,17 +577,17 @@ END
|
|
579
577
|
raise SyntaxError.new("Invalid tag: \"#{line}\".") unless match = line.scan(/%([-:\w]+)([-:\w\.\#]*)(.*)/)[0]
|
580
578
|
tag_name, attributes, rest = match
|
581
579
|
new_attributes_hash = old_attributes_hash = last_line = object_ref = nil
|
582
|
-
attributes_hashes =
|
580
|
+
attributes_hashes = []
|
583
581
|
while rest
|
584
582
|
case rest[0]
|
585
583
|
when ?{
|
586
584
|
break if old_attributes_hash
|
587
585
|
old_attributes_hash, rest, last_line = parse_old_attributes(rest)
|
588
|
-
attributes_hashes[:old
|
586
|
+
attributes_hashes << [:old, old_attributes_hash]
|
589
587
|
when ?(
|
590
588
|
break if new_attributes_hash
|
591
589
|
new_attributes_hash, rest, last_line = parse_new_attributes(rest)
|
592
|
-
attributes_hashes[:new
|
590
|
+
attributes_hashes << [:new, new_attributes_hash]
|
593
591
|
when ?[
|
594
592
|
break if object_ref
|
595
593
|
object_ref, rest = balance(rest, ?[, ?])
|
@@ -662,7 +660,7 @@ END
|
|
662
660
|
if type == :static
|
663
661
|
static_attributes[name] = val
|
664
662
|
else
|
665
|
-
dynamic_attributes <<
|
663
|
+
dynamic_attributes << name.inspect << " => " << val << ","
|
666
664
|
end
|
667
665
|
end
|
668
666
|
dynamic_attributes << "}"
|
@@ -697,7 +695,7 @@ END
|
|
697
695
|
|
698
696
|
return name, [:static, content.first[1]] if content.size == 1
|
699
697
|
return name, [:dynamic,
|
700
|
-
'"' + content.map {|(t, v)| t == :str ?
|
698
|
+
'"' + content.map {|(t, v)| t == :str ? v.inspect[1...-1] : "\#{#{v}}"}.join + '"']
|
701
699
|
end
|
702
700
|
|
703
701
|
# Parses a line that will render as an XHTML tag, and adds the code that will
|
@@ -757,21 +755,16 @@ END
|
|
757
755
|
object_ref = "nil" if object_ref.nil? || @options[:suppress_eval]
|
758
756
|
|
759
757
|
attributes = Precompiler.parse_class_and_id(attributes)
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
if attributes_hashes[:old]
|
769
|
-
static_attributes = parse_static_hash(attributes_hashes[:old])
|
758
|
+
attributes_hashes.map! do |syntax, attributes_hash|
|
759
|
+
if syntax == :old
|
760
|
+
static_attributes = parse_static_hash(attributes_hash)
|
761
|
+
attributes_hash = nil if static_attributes || @options[:suppress_eval]
|
762
|
+
else
|
763
|
+
static_attributes, attributes_hash = attributes_hash
|
764
|
+
end
|
770
765
|
Buffer.merge_attrs(attributes, static_attributes) if static_attributes
|
771
|
-
|
772
|
-
end
|
773
|
-
|
774
|
-
attributes_list.compact!
|
766
|
+
attributes_hash
|
767
|
+
end.compact!
|
775
768
|
|
776
769
|
raise SyntaxError.new("Illegal nesting: nesting within a self-closing tag is illegal.", @next_line.index) if block_opened? && self_closing
|
777
770
|
raise SyntaxError.new("There's no Ruby code for #{action} to evaluate.", last_line - 1) if parse && value.empty?
|
@@ -789,7 +782,7 @@ END
|
|
789
782
|
(nuke_inner_whitespace && block_opened?)
|
790
783
|
|
791
784
|
# Check if we can render the tag directly to text and not process it in the buffer
|
792
|
-
if object_ref == "nil" &&
|
785
|
+
if object_ref == "nil" && attributes_hashes.empty? && !preserve_script
|
793
786
|
tag_closed = !block_opened? && !self_closing && !parse
|
794
787
|
|
795
788
|
open_tag = prerender_tag(tag_name, self_closing, attributes)
|
@@ -807,19 +800,19 @@ END
|
|
807
800
|
return if tag_closed
|
808
801
|
else
|
809
802
|
flush_merged_text
|
810
|
-
content = parse ? 'nil' :
|
811
|
-
if
|
812
|
-
|
813
|
-
elsif
|
814
|
-
|
803
|
+
content = parse ? 'nil' : value.inspect
|
804
|
+
if attributes_hashes.empty?
|
805
|
+
attributes_hashes = ''
|
806
|
+
elsif attributes_hashes.size == 1
|
807
|
+
attributes_hashes = ", #{attributes_hashes.first}"
|
815
808
|
else
|
816
|
-
|
809
|
+
attributes_hashes = ", (#{attributes_hashes.join(").merge(")})"
|
817
810
|
end
|
818
811
|
|
819
812
|
args = [tag_name, self_closing, !block_opened?, preserve_tag, escape_html,
|
820
813
|
attributes, nuke_outer_whitespace, nuke_inner_whitespace
|
821
|
-
].map {|v|
|
822
|
-
push_silent "_hamlout.open_tag(#{args}, #{object_ref}, #{content}#{
|
814
|
+
].map { |v| v.inspect }.join(', ')
|
815
|
+
push_silent "_hamlout.open_tag(#{args}, #{object_ref}, #{content}#{attributes_hashes})"
|
823
816
|
@dont_tab_up_next_text = @dont_indent_next_line = dont_indent_next_line
|
824
817
|
end
|
825
818
|
|
@@ -1024,14 +1017,14 @@ END
|
|
1024
1017
|
|
1025
1018
|
def unescape_interpolation(str, opts = {})
|
1026
1019
|
res = ''
|
1027
|
-
rest = Haml::Shared.handle_interpolation
|
1020
|
+
rest = Haml::Shared.handle_interpolation str.dump do |scan|
|
1028
1021
|
escapes = (scan[2].size - 1) / 2
|
1029
1022
|
res << scan.matched[0...-3 - escapes]
|
1030
1023
|
if escapes % 2 == 1
|
1031
1024
|
res << '#{'
|
1032
1025
|
else
|
1033
1026
|
content = eval('"' + balance(scan, ?{, ?}, 1)[0][0...-1] + '"')
|
1034
|
-
content = "Haml::Helpers.html_escape(
|
1027
|
+
content = "Haml::Helpers.html_escape(#{content})" if opts[:escape_html]
|
1035
1028
|
res << '#{' + content + "}"# Use eval to get rid of string escapes
|
1036
1029
|
end
|
1037
1030
|
end
|
data/lib/haml/railtie.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
if Haml::Util.ap_geq_3? && !Haml::Util.ap_geq?("3.0.0.beta4")
|
2
2
|
raise <<ERROR
|
3
|
-
Haml
|
3
|
+
Haml no longer supports Rails 3 versions before beta 4.
|
4
4
|
Please upgrade to Rails 3.0.0.beta4 or later.
|
5
5
|
ERROR
|
6
6
|
end
|
@@ -8,12 +8,10 @@ end
|
|
8
8
|
# Rails 3.0.0.beta.2+
|
9
9
|
if defined?(ActiveSupport) && Haml::Util.has?(:public_method, ActiveSupport, :on_load)
|
10
10
|
require 'haml/template/options'
|
11
|
-
|
11
|
+
autoload(:Sass, 'sass/rails3_shim')
|
12
12
|
ActiveSupport.on_load(:before_initialize) do
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
# Haml requires AV, but Sass doesn't
|
13
|
+
# resolve autoload if it looks like they're using Sass without options
|
14
|
+
Sass if File.exist?(File.join(Rails.root, 'public/stylesheets/sass'))
|
17
15
|
ActiveSupport.on_load(:action_view) do
|
18
16
|
Haml.init_rails(binding)
|
19
17
|
end
|
data/lib/haml/template/plugin.rb
CHANGED
@@ -2,17 +2,12 @@
|
|
2
2
|
# using the > 2.0.1 template handler API.
|
3
3
|
|
4
4
|
module Haml
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
defined?(ActionView::Template::Handlers) &&
|
12
|
-
defined?(ActionView::Template::Handlers::Compilable))) &&
|
13
|
-
# In Rails 3.1+, we don't need to include Compilable.
|
14
|
-
Haml::Util.av_template_class(:Handlers)::ERB.include?(
|
15
|
-
Haml::Util.av_template_class(:Handlers)::Compilable)
|
5
|
+
class Plugin < Haml::Util.av_template_class(:Handler)
|
6
|
+
if (defined?(ActionView::TemplateHandlers) &&
|
7
|
+
defined?(ActionView::TemplateHandlers::Compilable)) ||
|
8
|
+
(defined?(ActionView::Template) &&
|
9
|
+
defined?(ActionView::Template::Handlers) &&
|
10
|
+
defined?(ActionView::Template::Handlers::Compilable))
|
16
11
|
include Haml::Util.av_template_class(:Handlers)::Compilable
|
17
12
|
end
|
18
13
|
|
@@ -34,11 +29,6 @@ module Haml
|
|
34
29
|
Haml::Engine.new(source, options).send(:precompiled_with_ambles, [])
|
35
30
|
end
|
36
31
|
|
37
|
-
# In Rails 3.1+, #call takes the place of #compile
|
38
|
-
def self.call(template)
|
39
|
-
new.compile(template)
|
40
|
-
end
|
41
|
-
|
42
32
|
def cache_fragment(block, name = {}, options = nil)
|
43
33
|
@view.fragment_for(block, name, options) do
|
44
34
|
eval("_hamlout.buffer", block.binding)
|
data/lib/haml/util.rb
CHANGED
@@ -6,7 +6,6 @@ require 'strscan'
|
|
6
6
|
require 'rbconfig'
|
7
7
|
|
8
8
|
require 'haml/root'
|
9
|
-
require 'haml/util/subset_map'
|
10
9
|
|
11
10
|
module Haml
|
12
11
|
# A module containing various useful functions.
|
@@ -17,11 +16,6 @@ module Haml
|
|
17
16
|
# @api public
|
18
17
|
RUBY_VERSION = ::RUBY_VERSION.split(".").map {|s| s.to_i}
|
19
18
|
|
20
|
-
# The Ruby engine we're running under. Defaults to `"ruby"`
|
21
|
-
# if the top-level constant is undefined.
|
22
|
-
# @api public
|
23
|
-
RUBY_ENGINE = defined?(::RUBY_ENGINE) ? ::RUBY_ENGINE : "ruby"
|
24
|
-
|
25
19
|
# Returns the path of a file relative to the Haml root directory.
|
26
20
|
#
|
27
21
|
# @param file [String] The filename relative to the Haml root
|
@@ -31,11 +25,10 @@ module Haml
|
|
31
25
|
end
|
32
26
|
|
33
27
|
# Converts an array of `[key, value]` pairs to a hash.
|
34
|
-
# For example:
|
35
|
-
#
|
36
|
-
# to_hash([[:foo, "bar"], [:baz, "bang"]])
|
37
|
-
# #=> {:foo => "bar", :baz => "bang"}
|
38
28
|
#
|
29
|
+
# @example
|
30
|
+
# to_hash([[:foo, "bar"], [:baz, "bang"]])
|
31
|
+
# #=> {:foo => "bar", :baz => "bang"}
|
39
32
|
# @param arr [Array<(Object, Object)>] An array of pairs
|
40
33
|
# @return [Hash] A hash
|
41
34
|
def to_hash(arr)
|
@@ -43,11 +36,10 @@ module Haml
|
|
43
36
|
end
|
44
37
|
|
45
38
|
# Maps the keys in a hash according to a block.
|
46
|
-
# For example:
|
47
|
-
#
|
48
|
-
# map_keys({:foo => "bar", :baz => "bang"}) {|k| k.to_s}
|
49
|
-
# #=> {"foo" => "bar", "baz" => "bang"}
|
50
39
|
#
|
40
|
+
# @example
|
41
|
+
# map_keys({:foo => "bar", :baz => "bang"}) {|k| k.to_s}
|
42
|
+
# #=> {"foo" => "bar", "baz" => "bang"}
|
51
43
|
# @param hash [Hash] The hash to map
|
52
44
|
# @yield [key] A block in which the keys are transformed
|
53
45
|
# @yieldparam key [Object] The key that should be mapped
|
@@ -60,11 +52,10 @@ module Haml
|
|
60
52
|
end
|
61
53
|
|
62
54
|
# Maps the values in a hash according to a block.
|
63
|
-
# For example:
|
64
|
-
#
|
65
|
-
# map_values({:foo => "bar", :baz => "bang"}) {|v| v.to_sym}
|
66
|
-
# #=> {:foo => :bar, :baz => :bang}
|
67
55
|
#
|
56
|
+
# @example
|
57
|
+
# map_values({:foo => "bar", :baz => "bang"}) {|v| v.to_sym}
|
58
|
+
# #=> {:foo => :bar, :baz => :bang}
|
68
59
|
# @param hash [Hash] The hash to map
|
69
60
|
# @yield [value] A block in which the values are transformed
|
70
61
|
# @yieldparam value [Object] The value that should be mapped
|
@@ -77,11 +68,10 @@ module Haml
|
|
77
68
|
end
|
78
69
|
|
79
70
|
# Maps the key-value pairs of a hash according to a block.
|
80
|
-
# For example:
|
81
|
-
#
|
82
|
-
# map_hash({:foo => "bar", :baz => "bang"}) {|k, v| [k.to_s, v.to_sym]}
|
83
|
-
# #=> {"foo" => :bar, "baz" => :bang}
|
84
71
|
#
|
72
|
+
# @example
|
73
|
+
# map_hash({:foo => "bar", :baz => "bang"}) {|k, v| [k.to_s, v.to_sym]}
|
74
|
+
# #=> {"foo" => :bar, "baz" => :bang}
|
85
75
|
# @param hash [Hash] The hash to map
|
86
76
|
# @yield [key, value] A block in which the key-value pairs are transformed
|
87
77
|
# @yieldparam [key] The hash key
|
@@ -96,11 +86,10 @@ module Haml
|
|
96
86
|
|
97
87
|
# Computes the powerset of the given array.
|
98
88
|
# This is the set of all subsets of the array.
|
99
|
-
# For example:
|
100
|
-
#
|
101
|
-
# powerset([1, 2, 3]) #=>
|
102
|
-
# Set[Set[], Set[1], Set[2], Set[3], Set[1, 2], Set[2, 3], Set[1, 3], Set[1, 2, 3]]
|
103
89
|
#
|
90
|
+
# @example
|
91
|
+
# powerset([1, 2, 3]) #=>
|
92
|
+
# Set[Set[], Set[1], Set[2], Set[3], Set[1, 2], Set[2, 3], Set[1, 3], Set[1, 2, 3]]
|
104
93
|
# @param arr [Enumerable]
|
105
94
|
# @return [Set<Set>] The subsets of `arr`
|
106
95
|
def powerset(arr)
|
@@ -127,11 +116,10 @@ module Haml
|
|
127
116
|
|
128
117
|
# Concatenates all strings that are adjacent in an array,
|
129
118
|
# while leaving other elements as they are.
|
130
|
-
# For example:
|
131
|
-
#
|
132
|
-
# merge_adjacent_strings([1, "foo", "bar", 2, "baz"])
|
133
|
-
# #=> [1, "foobar", 2, "baz"]
|
134
119
|
#
|
120
|
+
# @example
|
121
|
+
# merge_adjacent_strings([1, "foo", "bar", 2, "baz"])
|
122
|
+
# #=> [1, "foobar", 2, "baz"]
|
135
123
|
# @param enum [Enumerable]
|
136
124
|
# @return [Array] The enumerable with strings merged
|
137
125
|
def merge_adjacent_strings(enum)
|
@@ -194,11 +182,11 @@ module Haml
|
|
194
182
|
# @return [Array<Arrays>]
|
195
183
|
#
|
196
184
|
# @example
|
197
|
-
#
|
198
|
-
#
|
199
|
-
#
|
200
|
-
#
|
201
|
-
#
|
185
|
+
# paths([[1, 2], [3, 4], [5]]) #=>
|
186
|
+
# # [[1, 3, 5],
|
187
|
+
# # [2, 3, 5],
|
188
|
+
# # [1, 4, 5],
|
189
|
+
# # [2, 4, 5]]
|
202
190
|
def paths(arrs)
|
203
191
|
arrs.inject([[]]) do |paths, arr|
|
204
192
|
flatten(arr.map {|e| paths.map {|path| path + [e]}}, 1)
|
@@ -274,6 +262,43 @@ module Haml
|
|
274
262
|
version_gt(v1, v2) || !version_gt(v2, v1)
|
275
263
|
end
|
276
264
|
|
265
|
+
# A wrapper for `Marshal.dump` that calls `#_before_dump` on the object
|
266
|
+
# before dumping it, `#_after_dump` afterwards.
|
267
|
+
# It also calls `#_around_dump` and passes it a block in which the object is dumped.
|
268
|
+
#
|
269
|
+
# If any of these methods are undefined, they are not called.
|
270
|
+
#
|
271
|
+
# @param obj [Object] The object to dump.
|
272
|
+
# @return [String] The dumped data.
|
273
|
+
def dump(obj)
|
274
|
+
obj._before_dump if obj.respond_to?(:_before_dump)
|
275
|
+
return Marshal.dump(obj) unless obj.respond_to?(:_around_dump)
|
276
|
+
res = nil
|
277
|
+
obj._around_dump {res = Marshal.dump(obj)}
|
278
|
+
res
|
279
|
+
ensure
|
280
|
+
obj._after_dump if obj.respond_to?(:_after_dump)
|
281
|
+
end
|
282
|
+
|
283
|
+
# A wrapper for `Marshal.load` that calls `#_after_load` on the object
|
284
|
+
# after loading it, if it's defined.
|
285
|
+
#
|
286
|
+
# @param data [String] The data to load.
|
287
|
+
# @return [Object] The loaded object.
|
288
|
+
def load(data)
|
289
|
+
obj = Marshal.load(data)
|
290
|
+
obj._after_load if obj.respond_to?(:_after_load)
|
291
|
+
obj
|
292
|
+
end
|
293
|
+
|
294
|
+
# Throws a NotImplementedError for an abstract method.
|
295
|
+
#
|
296
|
+
# @param obj [Object] `self`
|
297
|
+
# @raise [NotImplementedError]
|
298
|
+
def abstract(obj)
|
299
|
+
raise NotImplementedError.new("#{obj.class} must implement ##{caller_info[2]}")
|
300
|
+
end
|
301
|
+
|
277
302
|
# Silence all output to STDERR within a block.
|
278
303
|
#
|
279
304
|
# @yield A block in which no output will be printed to STDERR
|
@@ -304,6 +329,35 @@ module Haml
|
|
304
329
|
warn(msg)
|
305
330
|
end
|
306
331
|
|
332
|
+
# Try loading Sass. If the `sass` gem isn't installed,
|
333
|
+
# print a warning and load from the vendored gem.
|
334
|
+
#
|
335
|
+
# @return [Boolean] True if Sass was successfully loaded from the `sass` gem,
|
336
|
+
# false otherwise.
|
337
|
+
def try_sass
|
338
|
+
return true if defined?(::SASS_BEGUN_TO_LOAD)
|
339
|
+
begin
|
340
|
+
require 'sass/version'
|
341
|
+
loaded = Sass.respond_to?(:version) && Sass.version[:major] &&
|
342
|
+
Sass.version[:minor] && ((Sass.version[:major] > 3 && Sass.version[:minor] > 1) ||
|
343
|
+
((Sass.version[:major] == 3 && Sass.version[:minor] == 1) &&
|
344
|
+
(Sass.version[:prerelease] || Sass.version[:name] != "Bleeding Edge")))
|
345
|
+
rescue LoadError => e
|
346
|
+
loaded = false
|
347
|
+
end
|
348
|
+
|
349
|
+
unless loaded
|
350
|
+
haml_warn(<<WARNING)
|
351
|
+
Sass is in the process of being separated from Haml,
|
352
|
+
and will no longer be bundled at all in Haml 3.2.0.
|
353
|
+
Please install the 'sass' gem if you want to use Sass.
|
354
|
+
WARNING
|
355
|
+
$".delete('sass/version')
|
356
|
+
$LOAD_PATH.unshift(scope("vendor/sass/lib"))
|
357
|
+
end
|
358
|
+
loaded
|
359
|
+
end
|
360
|
+
|
307
361
|
## Cross Rails Version Compatibility
|
308
362
|
|
309
363
|
# Returns the root of the Rails application,
|
@@ -420,25 +474,13 @@ module Haml
|
|
420
474
|
RbConfig::CONFIG['host_os'] =~ /mswin|windows|mingw/i
|
421
475
|
end
|
422
476
|
|
423
|
-
# Whether or not this is running on IronRuby.
|
424
|
-
#
|
425
|
-
# @return [Boolean]
|
426
|
-
def ironruby?
|
427
|
-
RUBY_ENGINE == "ironruby"
|
428
|
-
end
|
429
|
-
|
430
477
|
## Cross-Ruby-Version Compatibility
|
431
478
|
|
432
479
|
# Whether or not this is running under Ruby 1.8 or lower.
|
433
480
|
#
|
434
|
-
# Note that IronRuby counts as Ruby 1.8,
|
435
|
-
# because it doesn't support the Ruby 1.9 encoding API.
|
436
|
-
#
|
437
481
|
# @return [Boolean]
|
438
482
|
def ruby1_8?
|
439
|
-
|
440
|
-
# We have to fall back to 1.8 behavior.
|
441
|
-
ironruby? || (Haml::Util::RUBY_VERSION[0] == 1 && Haml::Util::RUBY_VERSION[1] < 9)
|
483
|
+
Haml::Util::RUBY_VERSION[0] == 1 && Haml::Util::RUBY_VERSION[1] < 9
|
442
484
|
end
|
443
485
|
|
444
486
|
# Whether or not this is running under Ruby 1.8.6 or lower.
|
@@ -488,7 +530,7 @@ MSG
|
|
488
530
|
# Like {\#check\_encoding}, but also checks for a Ruby-style `-# coding:` comment
|
489
531
|
# at the beginning of the template and uses that encoding if it exists.
|
490
532
|
#
|
491
|
-
# The
|
533
|
+
# The Haml encoding rules are simple.
|
492
534
|
# If a `-# coding:` comment exists,
|
493
535
|
# we assume that that's the original encoding of the document.
|
494
536
|
# Otherwise, we use whatever encoding Ruby has.
|
@@ -517,51 +559,6 @@ MSG
|
|
517
559
|
return check_encoding(str, &block)
|
518
560
|
end
|
519
561
|
|
520
|
-
# Like {\#check\_encoding}, but also checks for a `@charset` declaration
|
521
|
-
# at the beginning of the file and uses that encoding if it exists.
|
522
|
-
#
|
523
|
-
# The Sass encoding rules are simple.
|
524
|
-
# If a `@charset` declaration exists,
|
525
|
-
# we assume that that's the original encoding of the document.
|
526
|
-
# Otherwise, we use whatever encoding Ruby has.
|
527
|
-
# Then we convert that to UTF-8 to process internally.
|
528
|
-
# The UTF-8 end result is what's returned by this method.
|
529
|
-
#
|
530
|
-
# @param str [String] The string of which to check the encoding
|
531
|
-
# @yield [msg] A block in which an encoding error can be raised.
|
532
|
-
# Only yields if there is an encoding error
|
533
|
-
# @yieldparam msg [String] The error message to be raised
|
534
|
-
# @return [(String, Encoding)] The original string encoded as UTF-8,
|
535
|
-
# and the source encoding of the string (or `nil` under Ruby 1.8)
|
536
|
-
# @raise [Encoding::UndefinedConversionError] if the source encoding
|
537
|
-
# cannot be converted to UTF-8
|
538
|
-
# @raise [ArgumentError] if the document uses an unknown encoding with `@charset`
|
539
|
-
def check_sass_encoding(str, &block)
|
540
|
-
return check_encoding(str, &block), nil if ruby1_8?
|
541
|
-
# We allow any printable ASCII characters but double quotes in the charset decl
|
542
|
-
bin = str.dup.force_encoding("BINARY")
|
543
|
-
encoding = Haml::Util::ENCODINGS_TO_CHECK.find do |enc|
|
544
|
-
bin =~ Haml::Util::CHARSET_REGEXPS[enc]
|
545
|
-
end
|
546
|
-
charset, bom = $1, $2
|
547
|
-
if charset
|
548
|
-
charset = charset.force_encoding(encoding).encode("UTF-8")
|
549
|
-
if endianness = encoding[/[BL]E$/]
|
550
|
-
begin
|
551
|
-
Encoding.find(charset + endianness)
|
552
|
-
charset << endianness
|
553
|
-
rescue ArgumentError # Encoding charset + endianness doesn't exist
|
554
|
-
end
|
555
|
-
end
|
556
|
-
str.force_encoding(charset)
|
557
|
-
elsif bom
|
558
|
-
str.force_encoding(encoding)
|
559
|
-
end
|
560
|
-
|
561
|
-
str = check_encoding(str, &block)
|
562
|
-
return str.encode("UTF-8"), str.encoding
|
563
|
-
end
|
564
|
-
|
565
562
|
unless ruby1_8?
|
566
563
|
# @private
|
567
564
|
def _enc(string, encoding)
|
@@ -673,19 +670,6 @@ MSG
|
|
673
670
|
set1.to_a.uniq.sort_by {|e| e.hash}.eql?(set2.to_a.uniq.sort_by {|e| e.hash})
|
674
671
|
end
|
675
672
|
|
676
|
-
# Like `Object#inspect`, but preserves non-ASCII characters rather than escaping them under Ruby 1.9.2.
|
677
|
-
# This is necessary so that the precompiled Haml template can be `#encode`d into `@options[:encoding]`
|
678
|
-
# before being evaluated.
|
679
|
-
#
|
680
|
-
# @param obj {Object}
|
681
|
-
# @return {String}
|
682
|
-
def inspect_obj(obj)
|
683
|
-
return obj.inspect unless version_geq(::RUBY_VERSION, "1.9.2")
|
684
|
-
return ':' + inspect_obj(obj.to_s) if obj.is_a?(Symbol)
|
685
|
-
return obj.inspect unless obj.is_a?(String)
|
686
|
-
'"' + obj.gsub(/[\x00-\x7F]+/) {|s| s.inspect[1...-1]} + '"'
|
687
|
-
end
|
688
|
-
|
689
673
|
## Static Method Stuff
|
690
674
|
|
691
675
|
# The context in which the ERB for \{#def\_static\_method} will be run.
|