Module: Haml::Util
- Extended by:
- Util
- Defined in:
- lib/haml/util.rb,
lib/haml/template.rb
Overview
A module containing various useful functions.
Defined Under Namespace
Classes: StaticConditionalContext
Instance Method Summary collapse
-
#av_template_class(name)
Returns an ActionView::Template* class.
-
#balance(scanner, start, finish, count = 0) ⇒ (String, String)
Moves a scanner through a balanced pair of characters.
-
#caller_info(entry = caller[1]) ⇒ [String, Fixnum, (String, nil)]
Returns information about the caller of the previous method.
- #check_encoding(str)
-
#check_haml_encoding(str) {|msg| ... } ⇒ String
Like #check_encoding, but also checks for a Ruby-style
-# coding:
comment at the beginning of the template and uses that encoding if it exists. - #contains_interpolation?(str) ⇒ Boolean
-
#def_static_method(klass, name, args, *vars, erb)
This is used for methods in Buffer that need to be very fast, and take a lot of boolean parameters that are known at compile-time.
-
#handle_interpolation(str) {|scan| ... } ⇒ String
Scans through a string looking for the interoplation-opening
#{
and, when it’s found, yields the scanner to the calling code so it can handle it properly. -
#html_safe(text) ⇒ String?
Returns the given text, marked as being HTML-safe.
-
#human_indentation(indentation) ⇒ String
Formats a string for use in error messages about indentation.
-
#inspect_obj(obj) ⇒ String
Like
Object#inspect
, but preserves non-ASCII characters rather than escaping them under Ruby 1.9.2. -
#powerset(arr) ⇒ Set<Set>
Computes the powerset of the given array.
-
#rails_xss_safe? ⇒ Boolean
Whether or not ActionView’s XSS protection is available and enabled, as is the default for Rails 3.0+, and optional for version 2.3.5+.
-
#silence_warnings { ... }
Silence all output to STDERR within a block.
-
#static_method_name(name, *vars) ⇒ String
Computes the name for a method defined via #def_static_method.
- #unescape_interpolation(str, escape_html = nil)
Instance Method Details
#av_template_class(name)
Returns an ActionView::Template* class. In pre-3.0 versions of Rails, most of these classes were of the form ActionView::TemplateFoo
, while afterwards they were of the form ActionView;:Template::Foo
.
65 66 67 68 |
# File 'lib/haml/util.rb', line 65
def av_template_class(name)
return ActionView.const_get("Template#{name}") if ActionView.const_defined?("Template#{name}")
return ActionView::Template.const_get(name.to_s)
end
|
#balance(scanner, start, finish, count = 0) ⇒ (String, String)
Moves a scanner through a balanced pair of characters. For example:
Foo (Bar (Baz bang) bop) (Bang (bop bip))
^ ^
from to
295 296 297 298 299 300 301 302 303 304 305 |
# File 'lib/haml/util.rb', line 295
def balance(scanner, start, finish, count = 0)
str = ''
scanner = StringScanner.new(scanner) unless scanner.is_a? StringScanner
regexp = Regexp.new("(.*?)[\\#{start.chr}\\#{finish.chr}]", Regexp::MULTILINE)
while scanner.scan(regexp)
str << scanner.matched
count += 1 if scanner.matched[-1] == start
count -= 1 if scanner.matched[-1] == finish
return [str.strip, scanner.rest] if count == 0
end
end
|
#caller_info(entry = caller[1]) ⇒ [String, Fixnum, (String, nil)]
Returns information about the caller of the previous method.
39 40 41 42 43 44 45 |
# File 'lib/haml/util.rb', line 39
def caller_info(entry = caller[1])
info = entry.scan(/^(.*?):(-?.*?)(?::.*`(.+)')?$/).first
info[1] = info[1].to_i
# This is added by Rubinius to designate a block, but we don't care about it.
info[2].sub!(/ \{\}\Z/, '') if info[2]
info
end
|
#check_encoding(str)
103 104 105 |
# File 'lib/haml/util.rb', line 103
def check_encoding(str)
str.gsub(/\A\xEF\xBB\xBF/, '') # Get rid of the UTF-8 BOM
end
|
#check_haml_encoding(str) {|msg| ... } ⇒ String
Like #check_encoding, but also checks for a Ruby-style -# coding:
comment at the beginning of the template and uses that encoding if it exists.
The Haml encoding rules are simple. If a -# coding:
comment exists, we assume that that’s the original encoding of the document. Otherwise, we use whatever encoding Ruby has.
Haml uses the same rules for parsing coding comments as Ruby. This means that it can understand Emacs-style comments (e.g. -*- encoding: "utf-8" -*-
), and also that it cannot understand non-ASCII-compatible encodings such as UTF-16
and UTF-32
.
154 155 156 |
# File 'lib/haml/util.rb', line 154
def check_haml_encoding(str, &block)
check_encoding(str, &block)
end
|
#contains_interpolation?(str) ⇒ Boolean
324 325 326 |
# File 'lib/haml/util.rb', line 324
def contains_interpolation?(str)
str.include?('#{')
end
|
#def_static_method(klass, name, args, *vars, erb)
This is used for methods in Buffer that need to be very fast, and take a lot of boolean parameters that are known at compile-time. Instead of passing the parameters in normally, a separate method is defined for every possible combination of those parameters; these are then called using #static_method_name.
To define a static method, an ERB template for the method is provided. All conditionals based on the static parameters are done as embedded Ruby within this template. For example:
def_static_method(Foo, :my_static_method, [:foo, :bar], :baz, :bang, <<RUBY)
<% if baz && bang %>
return foo + bar
<% elsif baz || bang %>
return foo - bar
<% else %>
return 17
<% end %>
RUBY
#static_method_name can be used to call static methods.
238 239 240 241 242 243 244 245 246 247 248 249 250 251 |
# File 'lib/haml/util.rb', line 238
def def_static_method(klass, name, args, *vars)
erb = vars.pop
info = caller_info
powerset(vars).each do |set|
context = StaticConditionalContext.new(set).instance_eval {binding}
method_content = (defined?(Erubis::TinyEruby) && Erubis::TinyEruby || ERB).new(erb).result(context)
klass.class_eval(<<METHOD, info[0], info[1])
def #{static_method_name(name, *vars.map {|v| set.include?(v)})}(#{args.join(', ')})
#{method_content}
end
METHOD
end
end
|
#handle_interpolation(str) {|scan| ... } ⇒ String
Scans through a string looking for the interoplation-opening #{
and, when it’s found, yields the scanner to the calling code so it can handle it properly.
The scanner will have any backslashes immediately in front of the #{
as the second capture group (scan[2]
), and the text prior to that as the first (scan[1]
).
272 273 274 275 276 |
# File 'lib/haml/util.rb', line 272
def handle_interpolation(str)
scan = StringScanner.new(str)
yield scan while scan.scan(/(.*?)(\\*)\#\{/)
scan.rest
end
|
#html_safe(text) ⇒ String?
Returns the given text, marked as being HTML-safe. With older versions of the Rails XSS-safety mechanism, this destructively modifies the HTML-safety of text
.
87 88 89 90 |
# File 'lib/haml/util.rb', line 87
def html_safe(text)
return unless text
text.html_safe
end
|
#human_indentation(indentation) ⇒ String
Formats a string for use in error messages about indentation.
311 312 313 314 315 316 317 318 319 320 321 322 |
# File 'lib/haml/util.rb', line 311
def human_indentation(indentation)
if !indentation.include?(?\t)
noun = 'space'
elsif !indentation.include?(?\s)
noun = 'tab'
else
return indentation.inspect
end
singular = indentation.length == 1
"#{indentation.length} #{noun}#{'s' unless singular}"
end
|
#inspect_obj(obj) ⇒ String
Like Object#inspect
, but preserves non-ASCII characters rather than escaping them under Ruby 1.9.2. This is necessary so that the precompiled Haml template can be #encode
d into @options[:encoding]
before being evaluated.
181 182 183 |
# File 'lib/haml/util.rb', line 181
def inspect_obj(obj)
return obj.inspect
end
|
#powerset(arr) ⇒ Set<Set>
Computes the powerset of the given array. This is the set of all subsets of the array.
23 24 25 26 27 28 29 30 31 32 |
# File 'lib/haml/util.rb', line 23
def powerset(arr)
arr.inject([Set.new].to_set) do |powerset, el|
new_powerset = Set.new
powerset.each do |subset|
new_powerset << subset
new_powerset << subset + [el]
end
new_powerset
end
end
|
#rails_xss_safe? ⇒ Boolean
Whether or not ActionView’s XSS protection is available and enabled, as is the default for Rails 3.0+, and optional for version 2.3.5+. Overridden in haml/template.rb if this is the case.
77 78 79 |
# File 'lib/haml/util.rb', line 77
def rails_xss_safe?
false
end
|
#silence_warnings { ... }
Silence all output to STDERR within a block.
50 51 52 53 54 55 |
# File 'lib/haml/util.rb', line 50
def silence_warnings
the_real_stderr, $stderr = $stderr, StringIO.new
yield
ensure
$stderr = the_real_stderr
end
|
#static_method_name(name, *vars) ⇒ String
Computes the name for a method defined via #def_static_method.
258 259 260 |
# File 'lib/haml/util.rb', line 258
def static_method_name(name, *vars)
:"#{name}_#{vars.map {|v| !!v}.join('_')}"
end
|
#unescape_interpolation(str, escape_html = nil)
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 |
# File 'lib/haml/util.rb', line 328
def unescape_interpolation(str, escape_html = nil)
res = ''
rest = Haml::Util.handle_interpolation str.dump do |scan|
escapes = (scan[2].size - 1) / 2
res << scan.matched[0...-3 - escapes]
if escapes % 2 == 1
res << '#{'
else
content = eval('"' + balance(scan, ?{, ?}, 1)[0][0...-1] + '"')
content = "Haml::Helpers.html_escape((#{content}))" if escape_html
res << '#{' + content + "}"# Use eval to get rid of string escapes
end
end
res + rest
end
|