Module: Haml::Util
- Extended by:
- Util
- Included in:
- Buffer, Util, Version, Sass::Engine, Sass::Plugin, Sass::Script::Color
- Defined in:
- lib/haml/util.rb,
lib/haml/util/subset_map.rb
Overview
A module containing various useful functions.
Defined Under Namespace
Classes: StaticConditionalContext, SubsetMap
Constant Summary collapse
- RUBY_VERSION =
An array of ints representing the Ruby version number.
::RUBY_VERSION.split(".").map {|s| s.to_i}
- @@silence_warnings =
false
Instance Method Summary collapse
-
#ap_geq_3? ⇒ Boolean
Returns whether this environment is using ActionPack version 3.0.0 or greater.
-
#ap_geq_3_beta_3? ⇒ Boolean
Returns whether this environment is using ActionPack version 3.0.0.beta.3 or greater.
-
#assert_html_safe!(text)
Assert that a given object (usually a String) is HTML safe according to Rails' XSS handling, if it's loaded.
-
#av_template_class(name)
Returns an ActionView::Template* class.
-
#caller_info(entry = ) ⇒ [String, Fixnum, (String, nil)]
Returns information about the caller of the previous method.
-
#check_encoding(str) {|msg| ... } ⇒ String
Checks that the encoding of a string is valid in Ruby 1.9 and cleans up potential encoding gotchas like the UTF-8 BOM.
-
#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.
-
#enum_cons(enum, n) ⇒ Enumerator
A version of
Enumerable#enum_cons
that works in Ruby 1.8 and 1.9. -
#enum_slice(enum, n) ⇒ Enumerator
A version of
Enumerable#enum_slice
that works in Ruby 1.8 and 1.9. -
#enum_with_index(enum) ⇒ Enumerator
A version of
Enumerable#enum_with_index
that works in Ruby 1.8 and 1.9. -
#haml_warn(msg)
The same as
Kernel#warn
, but is silenced by #silence_haml_warnings. -
#has?(attr, klass, method) ⇒ Boolean
Checks to see if a class has a given method.
-
#html_safe(text) ⇒ String?
Returns the given text, marked as being HTML-safe.
-
#intersperse(enum, val) ⇒ Array
Intersperses a value in an enumerable, as would be done with
Array#join
but without concatenating the array together afterwards. -
#map_hash(hash) {|key, value| ... } ⇒ Hash
Maps the key-value pairs of a hash according to a block.
-
#map_keys(hash) {|key| ... } ⇒ Hash
Maps the keys in a hash according to a block.
-
#map_vals(hash) {|value| ... } ⇒ Hash
Maps the values in a hash according to a block.
-
#merge_adjacent_strings(enum) ⇒ Array
Concatenates all strings that are adjacent in an array, while leaving other elements as they are.
-
#ord(c) ⇒ Fixnum
Returns the ASCII code of the given character.
-
#paths(arrs) ⇒ Array<Arrays>
Return an array of all possible paths through the given arrays.
-
#powerset(arr) ⇒ Set<Set>
Computes the powerset of the given array.
-
#rails_env ⇒ String?
Returns the environment of the Rails application, if this is running in a Rails context.
-
#rails_root ⇒ String?
Returns the root of the Rails application, if this is running in a Rails context.
-
#rails_safe_buffer_class ⇒ Class
The class for the Rails SafeBuffer XSS protection class.
-
#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+.
-
#restrict(value, range) ⇒ Numeric
Restricts a number to falling within a given range.
-
#ruby1_8? ⇒ Boolean
Whether or not this is running under Ruby 1.8 or lower.
-
#scope(file) ⇒ String
Returns the path of a file relative to the Haml root directory.
-
#silence_haml_warnings { ... }
Silences all Haml warnings within a block.
-
#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.
-
#strip_string_array(arr) ⇒ Array
Destructively strips whitespace from the beginning and end of the first and last elements, respectively, in the array (if those elements are strings).
-
#substitute(ary, from, to)
Substitutes a sub-array of one array with another sub-array.
-
#to_hash(arr) ⇒ Hash
Converts an array of
[key, value]
pairs to a hash.
Instance Method Details
#ap_geq_3? ⇒ Boolean
Returns whether this environment is using ActionPack version 3.0.0 or greater.
265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 |
# File 'lib/haml/util.rb', line 265
def ap_geq_3?
# The ActionPack module is always loaded automatically in Rails >= 3
return false unless defined?(ActionPack) && defined?(ActionPack::VERSION)
version =
if defined?(ActionPack::VERSION::MAJOR)
ActionPack::VERSION::MAJOR
else
# Rails 1.2
ActionPack::VERSION::Major
end
# 3.0.0.beta1 acts more like ActionPack 2
# for purposes of this method
# (checking whether block helpers require = or -).
# This extra check can be removed when beta2 is out.
version >= 3 &&
!(defined?(ActionPack::VERSION::TINY) &&
ActionPack::VERSION::TINY == "0.beta")
end
|
#ap_geq_3_beta_3? ⇒ Boolean
Returns whether this environment is using ActionPack version 3.0.0.beta.3 or greater.
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 |
# File 'lib/haml/util.rb', line 290
def ap_geq_3_beta_3?
# The ActionPack module is always loaded automatically in Rails >= 3
return false unless defined?(ActionPack) && defined?(ActionPack::VERSION)
version =
if defined?(ActionPack::VERSION::MAJOR)
ActionPack::VERSION::MAJOR
else
# Rails 1.2
ActionPack::VERSION::Major
end
version >= 3 &&
((defined?(ActionPack::VERSION::TINY) &&
ActionPack::VERSION::TINY.is_a?(Fixnum) &&
ActionPack::VERSION::TINY >= 1) ||
(defined?(ActionPack::VERSION::BUILD) &&
ActionPack::VERSION::BUILD =~ /beta(\d+)/ &&
$1.to_i >= 3))
end
|
#assert_html_safe!(text)
Assert that a given object (usually a String) is HTML safe according to Rails' XSS handling, if it's loaded.
350 351 352 353 |
# File 'lib/haml/util.rb', line 350
def assert_html_safe!(text)
return unless rails_xss_safe? && text && !text.to_s.html_safe?
raise Haml::Error.new("Expected #{text.inspect} to be HTML-safe.")
end
|
#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
.
318 319 320 321 |
# File 'lib/haml/util.rb', line 318
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
|
#caller_info(entry = ) ⇒ [String, Fixnum, (String, nil)]
Returns information about the caller of the previous method.
201 202 203 204 205 |
# File 'lib/haml/util.rb', line 201
def caller_info(entry = caller[1])
info = entry.scan(/^(.*?):(-?.*?)(?::.*`(.+)')?$/).first
info[1] = info[1].to_i
info
end
|
#check_encoding(str) {|msg| ... } ⇒ String
Checks that the encoding of a string is valid in Ruby 1.9 and cleans up potential encoding gotchas like the UTF-8 BOM. If it's not, yields an error string describing the invalid character and the line on which it occurrs.
383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 |
# File 'lib/haml/util.rb', line 383
def check_encoding(str)
if ruby1_8?
return str.gsub(/\A\xEF\xBB\xBF/, '') # Get rid of the UTF-8 BOM
elsif str.valid_encoding?
# Get rid of the Unicode BOM if possible
if str.encoding.name =~ /^UTF-(8|16|32)(BE|LE)?$/
return str.gsub(Regexp.new("\\A\uFEFF".encode(str.encoding.name)), '')
else
return str
end
end
encoding = str.encoding
newlines = Regexp.new("\r\n|\r|\n".encode(encoding).force_encoding("binary"))
str.force_encoding("binary").split(newlines).each_with_index do |line, i|
begin
line.encode(encoding)
rescue Encoding::UndefinedConversionError => e
yield <<MSG.rstrip, i + 1
Invalid #{encoding.name} character #{e.error_char.dump}
MSG
end
end
return str
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.
512 513 514 515 516 517 518 519 520 521 522 523 |
# File 'lib/haml/util.rb', line 512
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}
klass.class_eval(<<METHOD, info[0], info[1])
def #{static_method_name(name, *vars.map {|v| set.include?(v)})}(#{args.join(', ')})
#{ERB.new(erb).result(context)}
end
METHOD
end
end
|
#enum_cons(enum, n) ⇒ Enumerator
A version of Enumerable#enum_cons
that works in Ruby 1.8 and 1.9.
440 441 442 |
# File 'lib/haml/util.rb', line 440
def enum_cons(enum, n)
ruby1_8? ? enum.enum_cons(n) : enum.each_cons(n)
end
|
#enum_slice(enum, n) ⇒ Enumerator
A version of Enumerable#enum_slice
that works in Ruby 1.8 and 1.9.
449 450 451 |
# File 'lib/haml/util.rb', line 449
def enum_slice(enum, n)
ruby1_8? ? enum.enum_slice(n) : enum.each_slice(n)
end
|
#enum_with_index(enum) ⇒ Enumerator
A version of Enumerable#enum_with_index
that works in Ruby 1.8 and 1.9.
431 432 433 |
# File 'lib/haml/util.rb', line 431
def enum_with_index(enum)
ruby1_8? ? enum.enum_with_index : enum.each_with_index
end
|
#haml_warn(msg)
The same as Kernel#warn
, but is silenced by #silence_haml_warnings.
232 233 234 235 |
# File 'lib/haml/util.rb', line 232
def haml_warn(msg)
return if @@silence_warnings
warn(msg)
end
|
#has?(attr, klass, method) ⇒ Boolean
Checks to see if a class has a given method. For example:
Haml::Util.has?(:public_instance_method, String, :gsub) #=> true
Method collections like Class#instance_methods
return strings in Ruby 1.8 and symbols in Ruby 1.9 and on,
so this handles checking for them in a compatible way.
423 424 425 |
# File 'lib/haml/util.rb', line 423
def has?(attr, klass, method)
klass.send("#{attr}s").include?(ruby1_8? ? method.to_s : method.to_sym)
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
.
340 341 342 343 344 |
# File 'lib/haml/util.rb', line 340
def html_safe(text)
return unless text
return text.html_safe if defined?(ActiveSupport::SafeBuffer)
text.html_safe!
end
|
#intersperse(enum, val) ⇒ Array
Intersperses a value in an enumerable, as would be done with Array#join
but without concatenating the array together afterwards.
146 147 148 |
# File 'lib/haml/util.rb', line 146
def intersperse(enum, val)
enum.inject([]) {|a, e| a << e << val}[0...-1]
end
|
#map_hash(hash) {|key, value| ... } ⇒ Hash
Maps the key-value pairs of a hash according to a block. For example:
map_hash({:foo => "bar", :baz => "bang"}) {|k, v| [k.to_s, v.to_sym]}
#=> {"foo" => :bar, "baz" => :bang}
85 86 87 |
# File 'lib/haml/util.rb', line 85
def map_hash(hash, &block)
to_hash(hash.map(&block))
end
|
#map_keys(hash) {|key| ... } ⇒ Hash
Maps the keys in a hash according to a block. For example:
map_keys({:foo => "bar", :baz => "bang"}) {|k| k.to_s}
#=> {"foo" => "bar", "baz" => "bang"}
50 51 52 |
# File 'lib/haml/util.rb', line 50
def map_keys(hash)
to_hash(hash.map {|k, v| [yield(k), v]})
end
|
#map_vals(hash) {|value| ... } ⇒ Hash
Maps the values in a hash according to a block. For example:
map_values({:foo => "bar", :baz => "bang"}) {|v| v.to_sym}
#=> {:foo => :bar, :baz => :bang}
67 68 69 |
# File 'lib/haml/util.rb', line 67
def map_vals(hash)
to_hash(hash.map {|k, v| [k, yield(v)]})
end
|
#merge_adjacent_strings(enum) ⇒ Array
Concatenates all strings that are adjacent in an array, while leaving other elements as they are. For example:
merge_adjacent_strings([1, "foo", "bar", 2, "baz"])
#=> [1, "foobar", 2, "baz"]
129 130 131 132 133 134 135 136 137 138 |
# File 'lib/haml/util.rb', line 129
def merge_adjacent_strings(enum)
e = enum.inject([]) do |a, e|
if e.is_a?(String) && a.last.is_a?(String)
a.last << e
else
a << e
end
a
end
end
|
#ord(c) ⇒ Fixnum
Returns the ASCII code of the given character.
457 458 459 |
# File 'lib/haml/util.rb', line 457
def ord(c)
ruby1_8? ? c[0] : c.ord
end
|
#paths(arrs) ⇒ Array<Arrays>
Return an array of all possible paths through the given arrays.
paths([[1, 2], [3, 4], [5]]) #=> # [[1, 3, 5], # [2, 3, 5], # [1, 4, 5], # [2, 4, 5]]
190 191 192 193 194 |
# File 'lib/haml/util.rb', line 190
def paths(arrs)
arrs.inject([[]]) do |paths, arr|
arr.map {|e| paths.map {|path| path + [e]}}.flatten(1)
end
end
|
#powerset(arr) ⇒ Set<Set>
Computes the powerset of the given array. This is the set of all subsets of the array. For example:
powerset([1, 2, 3]) #=>
Set[Set[], Set[1], Set[2], Set[3], Set[1, 2], Set[2, 3], Set[1, 3], Set[1, 2, 3]]
98 99 100 101 102 103 104 105 106 107 |
# File 'lib/haml/util.rb', line 98
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_env ⇒ String?
Returns the environment of the Rails application,
if this is running in a Rails context.
Returns nil
if no such environment is defined.
255 256 257 258 259 |
# File 'lib/haml/util.rb', line 255
def rails_env
return Rails.env.to_s if defined?(Rails.root)
return RAILS_ENV.to_s if defined?(RAILS_ENV)
return nil
end
|
#rails_root ⇒ String?
Returns the root of the Rails application,
if this is running in a Rails context.
Returns nil
if no such root is defined.
244 245 246 247 248 |
# File 'lib/haml/util.rb', line 244
def rails_root
return Rails.root.to_s if defined?(Rails.root)
return RAILS_ROOT.to_s if defined?(RAILS_ROOT)
return nil
end
|
#rails_safe_buffer_class ⇒ Class
The class for the Rails SafeBuffer XSS protection class. This varies depending on Rails version.
359 360 361 362 |
# File 'lib/haml/util.rb', line 359
def rails_safe_buffer_class
return ActionView::SafeBuffer if defined?(ActionView::SafeBuffer)
ActiveSupport::SafeBuffer
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.
330 331 332 |
# File 'lib/haml/util.rb', line 330
def rails_xss_safe?
false
end
|
#restrict(value, range) ⇒ Numeric
Restricts a number to falling within a given range. Returns the number if it falls within the range, or the closest value in the range if it doesn't.
116 117 118 |
# File 'lib/haml/util.rb', line 116
def restrict(value, range)
[[value, range.first].max, range.last].min
end
|
#ruby1_8? ⇒ Boolean
Whether or not this is running under Ruby 1.8 or lower.
369 370 371 |
# File 'lib/haml/util.rb', line 369
def ruby1_8?
Haml::Util::RUBY_VERSION[0] == 1 && Haml::Util::RUBY_VERSION[1] < 9
end
|
#scope(file) ⇒ String
Returns the path of a file relative to the Haml root directory.
21 22 23 |
# File 'lib/haml/util.rb', line 21
def scope(file)
File.join(Haml::ROOT_DIR, file)
end
|
#silence_haml_warnings { ... }
Silences all Haml warnings within a block.
221 222 223 224 225 226 227 |
# File 'lib/haml/util.rb', line 221
def silence_haml_warnings
old_silence_warnings = @@silence_warnings
@@silence_warnings = true
yield
ensure
@@silence_warnings = old_silence_warnings
end
|
#silence_warnings { ... }
Silence all output to STDERR within a block.
210 211 212 213 214 215 |
# File 'lib/haml/util.rb', line 210
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.
530 531 532 |
# File 'lib/haml/util.rb', line 530
def static_method_name(name, *vars)
"#{name}_#{vars.map {|v| !!v}.join('_')}"
end
|
#strip_string_array(arr) ⇒ Array
Destructively strips whitespace from the beginning and end of the first and last elements, respectively, in the array (if those elements are strings).
173 174 175 176 177 |
# File 'lib/haml/util.rb', line 173
def strip_string_array(arr)
arr.first.lstrip! if arr.first.is_a?(String)
arr.last.rstrip! if arr.last.is_a?(String)
arr
end
|
#substitute(ary, from, to)
Substitutes a sub-array of one array with another sub-array.
155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/haml/util.rb', line 155
def substitute(ary, from, to)
res = ary.dup
i = 0
while i < res.size
if res[i...i+from.size] == from
res[i...i+from.size] = to
end
i += 1
end
res
end
|
#to_hash(arr) ⇒ Hash
Converts an array of [key, value]
pairs to a hash.
For example:
to_hash([[:foo, "bar"], [:baz, "bang"]])
#=> {:foo => "bar", :baz => "bang"}
33 34 35 |
# File 'lib/haml/util.rb', line 33
def to_hash(arr)
arr.compact.inject({}) {|h, (k, v)| h[k] = v; h}
end
|