haml 3.2.0.alpha.13 → 3.2.0.alpha.14
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/CHANGELOG.md +17 -1
- data/REFERENCE.md +229 -385
- data/Rakefile +1 -1
- data/lib/haml/buffer.rb +1 -1
- data/lib/haml/compiler.rb +63 -26
- data/lib/haml/engine.rb +27 -118
- data/lib/haml/exec.rb +0 -77
- data/lib/haml/filters.rb +12 -9
- data/lib/haml/helpers.rb +3 -2
- data/lib/haml/options.rb +252 -0
- data/lib/haml/parser.rb +58 -59
- data/lib/haml/template.rb +3 -3
- data/lib/haml/template/plugin.rb +1 -1
- data/lib/haml/util.rb +37 -21
- data/lib/haml/version.rb +1 -1
- data/test/engine_test.rb +20 -2
- data/test/filters_test.rb +2 -2
- data/test/gemfiles/Gemfile.rails-3.0.x.lock +101 -0
- data/test/gemfiles/Gemfile.rails-3.1.x.lock +111 -0
- data/test/gemfiles/Gemfile.rails-3.2.x.lock +109 -0
- data/test/haml-spec/README.md +4 -4
- data/test/haml-spec/ruby_haml_test.rb +2 -2
- data/test/helper_test.rb +1 -1
- data/test/template_test.rb +72 -104
- data/test/test_helper.rb +2 -8
- data/test/util_test.rb +0 -4
- metadata +141 -153
- data/bin/html2haml +0 -7
- data/lib/haml/html.rb +0 -425
- data/lib/haml/html/erb.rb +0 -141
- data/test/html2haml/erb_tests.rb +0 -440
- data/test/html2haml_test.rb +0 -342
data/lib/haml/filters.rb
CHANGED
@@ -31,6 +31,9 @@ module Haml
|
|
31
31
|
# engine when there are more than one.
|
32
32
|
# @option options [String,Array<String>] :alias Any aliases for the filter.
|
33
33
|
# For example, :coffee is also available as :coffeescript.
|
34
|
+
# @option options [String] :extend The name of a module to extend when
|
35
|
+
# defining the filter. Defaults to "Plain". This allows filters such as
|
36
|
+
# Coffee to "inherit" from Javascript, wrapping its output in script tags.
|
34
37
|
# @since 3.2.0
|
35
38
|
def register_tilt_filter(name, options = {})
|
36
39
|
if constants.map(&:to_s).include?(name.to_s)
|
@@ -38,8 +41,8 @@ module Haml
|
|
38
41
|
end
|
39
42
|
|
40
43
|
filter = const_set(name, Module.new)
|
44
|
+
filter.extend const_get(options[:extend] || "Plain")
|
41
45
|
filter.extend TiltFilter
|
42
|
-
|
43
46
|
filter.extend PrecompiledTiltFilter if options.has_key? :precompiled
|
44
47
|
|
45
48
|
if options.has_key? :template_class
|
@@ -310,10 +313,10 @@ END
|
|
310
313
|
base.options = {}
|
311
314
|
base.instance_eval do
|
312
315
|
include Base
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
316
|
+
|
317
|
+
def render_with_options(text, compiler_options)
|
318
|
+
text = template_class.new(nil, 1, options) {text}.render
|
319
|
+
super(text, compiler_options)
|
317
320
|
end
|
318
321
|
end
|
319
322
|
end
|
@@ -332,13 +335,13 @@ END
|
|
332
335
|
end
|
333
336
|
|
334
337
|
# @!parse module Sass; end
|
335
|
-
register_tilt_filter "Sass"
|
338
|
+
register_tilt_filter "Sass", :extend => "Css"
|
336
339
|
|
337
340
|
# @!parse module Scss; end
|
338
|
-
register_tilt_filter "Scss"
|
341
|
+
register_tilt_filter "Scss", :extend => "Css"
|
339
342
|
|
340
343
|
# @!parse module Less; end
|
341
|
-
register_tilt_filter "Less"
|
344
|
+
register_tilt_filter "Less", :extend => "Css"
|
342
345
|
|
343
346
|
# @!parse module Markdown; end
|
344
347
|
register_tilt_filter "Markdown"
|
@@ -347,7 +350,7 @@ END
|
|
347
350
|
register_tilt_filter "Erb", :precompiled => true
|
348
351
|
|
349
352
|
# @!parse module Coffee; end
|
350
|
-
register_tilt_filter "Coffee", :alias => "coffeescript"
|
353
|
+
register_tilt_filter "Coffee", :alias => "coffeescript", :extend => "Javascript"
|
351
354
|
|
352
355
|
# Parses the filtered text with ERB.
|
353
356
|
# Not available if the {file:REFERENCE.md#suppress_eval-option
|
data/lib/haml/helpers.rb
CHANGED
@@ -70,7 +70,7 @@ MESSAGE
|
|
70
70
|
# context.haml_tag :p, "Stuff"
|
71
71
|
#
|
72
72
|
def init_haml_helpers
|
73
|
-
@haml_buffer = Haml::Buffer.new(haml_buffer,
|
73
|
+
@haml_buffer = Haml::Buffer.new(haml_buffer, Options.new.for_buffer)
|
74
74
|
nil
|
75
75
|
end
|
76
76
|
|
@@ -190,6 +190,7 @@ MESSAGE
|
|
190
190
|
# @yield [item] A block which contains Haml code that goes within list items
|
191
191
|
# @yieldparam item An element of `enum`
|
192
192
|
def list_of(enum, opts={}, &block)
|
193
|
+
opts_attributes = opts.empty? ? "" : " ".<<(opts.map{|k,v| "#{k}='#{v}'" }.join(" "))
|
193
194
|
to_return = enum.collect do |i|
|
194
195
|
result = capture_haml(i, &block)
|
195
196
|
|
@@ -200,7 +201,7 @@ MESSAGE
|
|
200
201
|
result = result.strip
|
201
202
|
end
|
202
203
|
|
203
|
-
%Q!<li#{
|
204
|
+
%Q!<li#{opts_attributes}>#{result}</li>!
|
204
205
|
end
|
205
206
|
to_return.join("\n")
|
206
207
|
end
|
data/lib/haml/options.rb
ADDED
@@ -0,0 +1,252 @@
|
|
1
|
+
module Haml
|
2
|
+
# This class encapsulates all of the configuration options that Haml
|
3
|
+
# understands. Please see the {file:REFERENCE.md#options Haml Reference} to
|
4
|
+
# learn how to set the options.
|
5
|
+
class Options
|
6
|
+
|
7
|
+
@defaults = {
|
8
|
+
:attr_wrapper => "'",
|
9
|
+
:autoclose => %w(meta img link br hr input area param col base),
|
10
|
+
:encoding => "UTF-8",
|
11
|
+
:escape_attrs => true,
|
12
|
+
:escape_html => false,
|
13
|
+
:filename => '(haml)',
|
14
|
+
:format => :xhtml,
|
15
|
+
:hyphenate_data_attrs => true,
|
16
|
+
:line => 1,
|
17
|
+
:mime_type => 'text/html',
|
18
|
+
:preserve => %w(textarea pre code),
|
19
|
+
:remove_whitespace => false,
|
20
|
+
:suppress_eval => false,
|
21
|
+
:ugly => false
|
22
|
+
}
|
23
|
+
|
24
|
+
@valid_formats = [:xhtml, :html4, :html5]
|
25
|
+
|
26
|
+
@buffer_option_keys = [:autoclose, :preserve, :attr_wrapper, :ugly, :format,
|
27
|
+
:encoding, :escape_html, :escape_attrs, :hyphenate_data_attrs]
|
28
|
+
|
29
|
+
# The default option values.
|
30
|
+
# @return Hash
|
31
|
+
def self.defaults
|
32
|
+
@defaults
|
33
|
+
end
|
34
|
+
|
35
|
+
# An array of valid values for the `:format` option.
|
36
|
+
# @return Array
|
37
|
+
def self.valid_formats
|
38
|
+
@valid_formats
|
39
|
+
end
|
40
|
+
|
41
|
+
# An array of keys that will be used to provide a hash of options to
|
42
|
+
# {Haml::Buffer}.
|
43
|
+
# @return Hash
|
44
|
+
def self.buffer_option_keys
|
45
|
+
@buffer_option_keys
|
46
|
+
end
|
47
|
+
|
48
|
+
# The character that should wrap element attributes. This defaults to `'`
|
49
|
+
# (an apostrophe). Characters of this type within the attributes will be
|
50
|
+
# escaped (e.g. by replacing them with `'`) if the character is an
|
51
|
+
# apostrophe or a quotation mark.
|
52
|
+
attr_reader :attr_wrapper
|
53
|
+
|
54
|
+
# A list of tag names that should be automatically self-closed if they have
|
55
|
+
# no content. This can also contain regular expressions that match tag names
|
56
|
+
# (or any object which responds to `#===`). Defaults to `['meta', 'img',
|
57
|
+
# 'link', 'br', 'hr', 'input', 'area', 'param', 'col', 'base']`.
|
58
|
+
attr_accessor :autoclose
|
59
|
+
|
60
|
+
# The encoding to use for the HTML output.
|
61
|
+
# Only available on Ruby 1.9 or higher.
|
62
|
+
# This can be a string or an `Encoding` Object. Note that Haml **does not**
|
63
|
+
# automatically re-encode Ruby values; any strings coming from outside the
|
64
|
+
# application should be converted before being passed into the Haml
|
65
|
+
# template. Defaults to `Encoding.default_internal`; if that's not set,
|
66
|
+
# defaults to the encoding of the Haml template; if that's `US-ASCII`,
|
67
|
+
# defaults to `"UTF-8"`.
|
68
|
+
attr_reader :encoding
|
69
|
+
|
70
|
+
# Sets whether or not to escape HTML-sensitive characters in attributes. If
|
71
|
+
# this is true, all HTML-sensitive characters in attributes are escaped. If
|
72
|
+
# it's set to false, no HTML-sensitive characters in attributes are escaped.
|
73
|
+
# If it's set to `:once`, existing HTML escape sequences are preserved, but
|
74
|
+
# other HTML-sensitive characters are escaped.
|
75
|
+
#
|
76
|
+
# Defaults to `true`.
|
77
|
+
attr_accessor :escape_attrs
|
78
|
+
|
79
|
+
# Sets whether or not to escape HTML-sensitive characters in script. If this
|
80
|
+
# is true, `=` behaves like {file:REFERENCE.md#escaping_html `&=`};
|
81
|
+
# otherwise, it behaves like {file:REFERENCE.md#unescaping_html `!=`}. Note
|
82
|
+
# that if this is set, `!=` should be used for yielding to subtemplates and
|
83
|
+
# rendering partials. See also {file:REFERENCE.md#escaping_html Escaping HTML} and
|
84
|
+
# {file:REFERENCE.md#unescaping_html Unescaping HTML}.
|
85
|
+
#
|
86
|
+
# Defaults to false.
|
87
|
+
attr_accessor :escape_html
|
88
|
+
|
89
|
+
# The name of the Haml file being parsed.
|
90
|
+
# This is only used as information when exceptions are raised. This is
|
91
|
+
# automatically assigned when working through ActionView, so it's really
|
92
|
+
# only useful for the user to assign when dealing with Haml programatically.
|
93
|
+
attr_accessor :filename
|
94
|
+
|
95
|
+
# If set to `true`, Haml will convert underscores to hyphens in all
|
96
|
+
# {file:REFERENCE.md#html5_custom_data_attributes Custom Data Attributes} As
|
97
|
+
# of Haml 3.2, this defaults to `true`.
|
98
|
+
attr_accessor :hyphenate_data_attrs
|
99
|
+
|
100
|
+
# The line offset of the Haml template being parsed. This is useful for
|
101
|
+
# inline templates, similar to the last argument to `Kernel#eval`.
|
102
|
+
attr_accessor :line
|
103
|
+
|
104
|
+
# Determines the output format. Normally the default is `:xhtml`, although
|
105
|
+
# under Rails 3 it's `:html5`, since that's the Rails 3's default format.
|
106
|
+
# Other options are `:html4` and `:html5`, which are identical to `:xhtml`
|
107
|
+
# except there are no self-closing tags, the XML prolog is ignored and
|
108
|
+
# correct DOCTYPEs are generated.
|
109
|
+
#
|
110
|
+
# If the mime_type of the template being rendered is `text/xml` then a
|
111
|
+
# format of `:xhtml` will be used even if the global output format is set to
|
112
|
+
# `:html4` or `:html5`.
|
113
|
+
attr :format
|
114
|
+
|
115
|
+
# The mime type that the rendered document will be served with. If this is
|
116
|
+
# set to `text/xml` then the format will be overridden to `:xhtml` even if
|
117
|
+
# it has set to `:html4` or `:html5`.
|
118
|
+
attr_accessor :mime_type
|
119
|
+
|
120
|
+
# A list of tag names that should automatically have their newlines
|
121
|
+
# preserved using the {Haml::Helpers#preserve} helper. This means that any
|
122
|
+
# content given on the same line as the tag will be preserved. For example,
|
123
|
+
# `%textarea= "Foo\nBar"` compiles to `<textarea>Foo
Bar</textarea>`.
|
124
|
+
# Defaults to `['textarea', 'pre']`. See also
|
125
|
+
# {file:REFERENCE.md#whitespace_preservation Whitespace Preservation}.
|
126
|
+
attr_accessor :preserve
|
127
|
+
|
128
|
+
# If set to `true`, all tags are treated as if both
|
129
|
+
# {file:REFERENCE.md#whitespace_removal__and_ whitespace removal} options
|
130
|
+
# were present. Use with caution as this may cause whitespace-related
|
131
|
+
# formatting errors.
|
132
|
+
#
|
133
|
+
# Defaults to `false`.
|
134
|
+
attr_reader :remove_whitespace
|
135
|
+
|
136
|
+
# Whether or not attribute hashes and Ruby scripts designated by `=` or `~`
|
137
|
+
# should be evaluated. If this is `true`, said scripts are rendered as empty
|
138
|
+
# strings.
|
139
|
+
#
|
140
|
+
# Defaults to `false`.
|
141
|
+
attr_accessor :suppress_eval
|
142
|
+
|
143
|
+
# If set to `true`, Haml makes no attempt to properly indent or format the
|
144
|
+
# HTML output. This significantly improves rendering performance but makes
|
145
|
+
# viewing the source unpleasant.
|
146
|
+
#
|
147
|
+
# Defaults to `true` in Rails production mode, and `false` everywhere else.
|
148
|
+
attr_accessor :ugly
|
149
|
+
|
150
|
+
def initialize(values = {}, &block)
|
151
|
+
defaults.each {|k, v| instance_variable_set :"@#{k}", v}
|
152
|
+
values.reject {|k, v| !defaults.has_key?(k) || v.nil?}.each {|k, v| send("#{k}=", v)}
|
153
|
+
yield if block_given?
|
154
|
+
end
|
155
|
+
|
156
|
+
# Retrieve an option value.
|
157
|
+
# @param key The value to retrieve.
|
158
|
+
def [](key)
|
159
|
+
send key
|
160
|
+
end
|
161
|
+
|
162
|
+
# Set an option value.
|
163
|
+
# @param key The key to set.
|
164
|
+
# @param value The value to set for the key.
|
165
|
+
def []=(key, value)
|
166
|
+
send "#{key}=", value
|
167
|
+
end
|
168
|
+
|
169
|
+
[:escape_attrs, :hyphenate_data_attrs, :remove_whitespace, :suppress_eval,
|
170
|
+
:ugly].each do |method|
|
171
|
+
class_eval(<<-END)
|
172
|
+
def #{method}?
|
173
|
+
!! @#{method}
|
174
|
+
end
|
175
|
+
END
|
176
|
+
end
|
177
|
+
|
178
|
+
# @return [Boolean] Whether or not the format is XHTML.
|
179
|
+
def xhtml?
|
180
|
+
not html?
|
181
|
+
end
|
182
|
+
|
183
|
+
# @return [Boolean] Whether or not the format is any flavor of HTML.
|
184
|
+
def html?
|
185
|
+
html4? or html5?
|
186
|
+
end
|
187
|
+
|
188
|
+
# @return [Boolean] Whether or not the format is HTML4.
|
189
|
+
def html4?
|
190
|
+
format == :html4
|
191
|
+
end
|
192
|
+
|
193
|
+
# @return [Boolean] Whether or not the format is HTML5.
|
194
|
+
def html5?
|
195
|
+
format == :html5
|
196
|
+
end
|
197
|
+
|
198
|
+
def attr_wrapper=(value)
|
199
|
+
@attr_wrapper = value || self.class.defaults[:attr_wrapper]
|
200
|
+
end
|
201
|
+
|
202
|
+
# Undef :format to suppress warning. It's defined above with the `:attr`
|
203
|
+
# macro in order to make it appear in Yard's list of instance attributes.
|
204
|
+
undef :format
|
205
|
+
def format
|
206
|
+
mime_type == "text/xml" ? "xhtml" : @format
|
207
|
+
end
|
208
|
+
|
209
|
+
def format=(value)
|
210
|
+
unless self.class.valid_formats.include?(value)
|
211
|
+
raise Haml::Error, "Invalid output format #{value.inspect}"
|
212
|
+
end
|
213
|
+
@format = value
|
214
|
+
end
|
215
|
+
|
216
|
+
def remove_whitespace=(value)
|
217
|
+
@ugly = true if value
|
218
|
+
@remove_whitespace = value
|
219
|
+
end
|
220
|
+
|
221
|
+
if RUBY_VERSION < "1.9"
|
222
|
+
attr_writer :encoding
|
223
|
+
else
|
224
|
+
def encoding=(value)
|
225
|
+
return unless value
|
226
|
+
@encoding = value.is_a?(Encoding) ? value.name : value.to_s
|
227
|
+
@encoding = "UTF-8" if @encoding.upcase == "US-ASCII"
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
# Returns a subset of options: those that {Haml::Buffer} cares about.
|
232
|
+
# All of the values here are such that when `#inspect` is called on the hash,
|
233
|
+
# it can be `Kernel#eval`ed to get the same result back.
|
234
|
+
#
|
235
|
+
# See {file:REFERENCE.md#options the Haml options documentation}.
|
236
|
+
#
|
237
|
+
# @return [{Symbol => Object}] The options hash
|
238
|
+
def for_buffer
|
239
|
+
self.class.buffer_option_keys.inject({}) do |hash, key|
|
240
|
+
hash[key] = send(key)
|
241
|
+
hash
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
private
|
246
|
+
|
247
|
+
def defaults
|
248
|
+
self.class.defaults
|
249
|
+
end
|
250
|
+
|
251
|
+
end
|
252
|
+
end
|
data/lib/haml/parser.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'strscan'
|
2
2
|
|
3
3
|
module Haml
|
4
|
-
|
4
|
+
class Parser
|
5
5
|
include Haml::Util
|
6
6
|
|
7
7
|
# Designates an XHTML/XML element.
|
@@ -75,6 +75,58 @@ module Haml
|
|
75
75
|
# The Regex that matches a literal string or symbol value
|
76
76
|
LITERAL_VALUE_REGEX = /:(\w*)|(["'])((?![\\#]|\2).|\\.)*\2/
|
77
77
|
|
78
|
+
def initialize(template, options)
|
79
|
+
# :eod is a special end-of-document marker
|
80
|
+
@template = (template.rstrip).split(/\r\n|\r|\n/) + [:eod, :eod]
|
81
|
+
@options = options
|
82
|
+
@flat = false
|
83
|
+
@index = 0
|
84
|
+
@template_index = 0
|
85
|
+
@template_tabs = 0
|
86
|
+
end
|
87
|
+
|
88
|
+
def parse
|
89
|
+
@root = @parent = ParseNode.new(:root)
|
90
|
+
@haml_comment = false
|
91
|
+
@indentation = nil
|
92
|
+
@line = next_line
|
93
|
+
|
94
|
+
raise SyntaxError.new("Indenting at the beginning of the document is illegal.", @line.index) if @line.tabs != 0
|
95
|
+
|
96
|
+
while next_line
|
97
|
+
process_indent(@line) unless @line.text.empty?
|
98
|
+
|
99
|
+
if flat?
|
100
|
+
text = @line.full.dup
|
101
|
+
text = "" unless text.gsub!(/^#{@flat_spaces}/, '')
|
102
|
+
@filter_buffer << "#{text}\n"
|
103
|
+
@line = @next_line
|
104
|
+
next
|
105
|
+
end
|
106
|
+
|
107
|
+
@tab_up = nil
|
108
|
+
process_line(@line.text, @line.index) unless @line.text.empty? || @haml_comment
|
109
|
+
if @parent.type != :haml_comment && (block_opened? || @tab_up)
|
110
|
+
@template_tabs += 1
|
111
|
+
@parent = @parent.children.last
|
112
|
+
end
|
113
|
+
|
114
|
+
if !@haml_comment && !flat? && @next_line.tabs - @line.tabs > 1
|
115
|
+
raise SyntaxError.new("The line was indented #{@next_line.tabs - @line.tabs} levels deeper than the previous line.", @next_line.index)
|
116
|
+
end
|
117
|
+
|
118
|
+
@line = @next_line
|
119
|
+
end
|
120
|
+
|
121
|
+
# Close all the open tags
|
122
|
+
close until @parent.type == :root
|
123
|
+
@root
|
124
|
+
rescue Haml::Error => e
|
125
|
+
e.backtrace.unshift "#{@options[:filename]}:#{(e.line ? e.line + 1 : @index) + @options[:line] - 1}"
|
126
|
+
raise
|
127
|
+
end
|
128
|
+
|
129
|
+
|
78
130
|
private
|
79
131
|
|
80
132
|
# @private
|
@@ -124,44 +176,6 @@ END
|
|
124
176
|
end
|
125
177
|
end
|
126
178
|
|
127
|
-
def parse
|
128
|
-
@root = @parent = ParseNode.new(:root)
|
129
|
-
@haml_comment = false
|
130
|
-
@indentation = nil
|
131
|
-
@line = next_line
|
132
|
-
|
133
|
-
raise SyntaxError.new("Indenting at the beginning of the document is illegal.", @line.index) if @line.tabs != 0
|
134
|
-
|
135
|
-
while next_line
|
136
|
-
process_indent(@line) unless @line.text.empty?
|
137
|
-
|
138
|
-
if flat?
|
139
|
-
text = @line.full.dup
|
140
|
-
text = "" unless text.gsub!(/^#{@flat_spaces}/, '')
|
141
|
-
@filter_buffer << "#{text}\n"
|
142
|
-
@line = @next_line
|
143
|
-
next
|
144
|
-
end
|
145
|
-
|
146
|
-
@tab_up = nil
|
147
|
-
process_line(@line.text, @line.index) unless @line.text.empty? || @haml_comment
|
148
|
-
if @parent.type != :haml_comment && (block_opened? || @tab_up)
|
149
|
-
@template_tabs += 1
|
150
|
-
@parent = @parent.children.last
|
151
|
-
end
|
152
|
-
|
153
|
-
if !@haml_comment && !flat? && @next_line.tabs - @line.tabs > 1
|
154
|
-
raise SyntaxError.new("The line was indented #{@next_line.tabs - @line.tabs} levels deeper than the previous line.", @next_line.index)
|
155
|
-
end
|
156
|
-
|
157
|
-
@line = @next_line
|
158
|
-
end
|
159
|
-
|
160
|
-
# Close all the open tags
|
161
|
-
close until @parent.type == :root
|
162
|
-
@root
|
163
|
-
end
|
164
|
-
|
165
179
|
# Processes and deals with lowering indentation.
|
166
180
|
def process_indent(line)
|
167
181
|
return unless line.tabs <= @template_tabs && @template_tabs > 0
|
@@ -491,6 +505,11 @@ END
|
|
491
505
|
nuke_inner_whitespace = nuke_whitespace.include? '<'
|
492
506
|
end
|
493
507
|
|
508
|
+
if @options[:remove_whitespace]
|
509
|
+
nuke_outer_whitespace = true
|
510
|
+
nuke_inner_whitespace = true
|
511
|
+
end
|
512
|
+
|
494
513
|
value = value.to_s.strip
|
495
514
|
[tag_name, attributes, attributes_hashes, object_ref, nuke_outer_whitespace,
|
496
515
|
nuke_inner_whitespace, action, value, last_line || @index]
|
@@ -675,26 +694,6 @@ END
|
|
675
694
|
!((text[-3..-2] =~ /\W\?/) || text[-3..-2] == "?\\")
|
676
695
|
end
|
677
696
|
|
678
|
-
def contains_interpolation?(str)
|
679
|
-
str.include?('#{')
|
680
|
-
end
|
681
|
-
|
682
|
-
def unescape_interpolation(str, escape_html = nil)
|
683
|
-
res = ''
|
684
|
-
rest = Haml::Util.handle_interpolation str.dump do |scan|
|
685
|
-
escapes = (scan[2].size - 1) / 2
|
686
|
-
res << scan.matched[0...-3 - escapes]
|
687
|
-
if escapes % 2 == 1
|
688
|
-
res << '#{'
|
689
|
-
else
|
690
|
-
content = eval('"' + balance(scan, ?{, ?}, 1)[0][0...-1] + '"')
|
691
|
-
content = "Haml::Helpers.html_escape((#{content}))" if escape_html
|
692
|
-
res << '#{' + content + "}"# Use eval to get rid of string escapes
|
693
|
-
end
|
694
|
-
end
|
695
|
-
res + rest
|
696
|
-
end
|
697
|
-
|
698
697
|
def balance(*args)
|
699
698
|
res = Haml::Util.balance(*args)
|
700
699
|
return res if res
|