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. -
#flatten(arr, n) ⇒ Array
Flattens the first
n
nested arrays in a cross-version manner. -
#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. -
#lcs(x, y) {|a, b| ... } ⇒ Array
Computes a single longest common subsequence for
x
andy
. -
#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.
-
#ruby1_8_6? ⇒ Boolean
Whether or not this is running under Ruby 1.8.6 or lower.
-
#scope(file) ⇒ String
Returns the path of a file relative to the Haml root directory.
-
#set_eql?(set1, set2) ⇒ Boolean
Tests the hash-equality of two sets in a cross-version manner.
-
#set_hash(set) ⇒ Fixnum
Returns the hash code for a set in a cross-version manner.
-
#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.
286 287 288 289 290 291 292 293 294 295 296 297 298 299 |
# File 'lib/haml/util.rb', line 286
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
version >= 3
end
|
#ap_geq_3_beta_3? ⇒ Boolean
Returns whether this environment is using ActionPack version 3.0.0.beta.3 or greater.
305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 |
# File 'lib/haml/util.rb', line 305
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.
365 366 367 368 |
# File 'lib/haml/util.rb', line 365
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
.
333 334 335 336 |
# File 'lib/haml/util.rb', line 333
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.
219 220 221 222 223 |
# File 'lib/haml/util.rb', line 219
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.
406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 |
# File 'lib/haml/util.rb', line 406
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.
567 568 569 570 571 572 573 574 575 576 577 578 |
# File 'lib/haml/util.rb', line 567
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.
463 464 465 |
# File 'lib/haml/util.rb', line 463
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.
472 473 474 |
# File 'lib/haml/util.rb', line 472
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.
454 455 456 |
# File 'lib/haml/util.rb', line 454
def enum_with_index(enum)
ruby1_8? ? enum.enum_with_index : enum.each_with_index
end
|
#flatten(arr, n) ⇒ Array
Flattens the first n
nested arrays in a cross-version manner.
489 490 491 492 493 |
# File 'lib/haml/util.rb', line 489
def flatten(arr, n)
return arr.flatten(n) unless ruby1_8_6?
return arr if n == 0
arr.inject([]) {|res, e| e.is_a?(Array) ? res.concat(flatten(e, n - 1)) : res << e}
end
|
#haml_warn(msg)
The same as Kernel#warn
, but is silenced by #silence_haml_warnings.
250 251 252 253 |
# File 'lib/haml/util.rb', line 250
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.
446 447 448 |
# File 'lib/haml/util.rb', line 446
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
.
355 356 357 358 359 |
# File 'lib/haml/util.rb', line 355
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
|
#lcs(x, y) {|a, b| ... } ⇒ Array
Computes a single longest common subsequence for x
and y
.
If there are more than one longest common subsequences,
the one returned is that which starts first in x
.
207 208 209 210 211 212 |
# File 'lib/haml/util.rb', line 207
def lcs(x, y, &block)
x = [nil, *x]
y = [nil, *y]
block ||= proc {|a, b| a == b && a}
lcs_backtrace(lcs_table(x, y, &block), x, y, x.size-1, y.size-1, &block)
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.
480 481 482 |
# File 'lib/haml/util.rb', line 480
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|
flatten(arr.map {|e| paths.map {|path| path + [e]}}, 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.
276 277 278 279 280 |
# File 'lib/haml/util.rb', line 276
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.
262 263 264 265 266 267 268 269 |
# File 'lib/haml/util.rb', line 262
def rails_root
if defined?(Rails.root)
return Rails.root.to_s if Rails.root
raise "ERROR: Rails.root is nil!"
end
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.
374 375 376 377 |
# File 'lib/haml/util.rb', line 374
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.
345 346 347 |
# File 'lib/haml/util.rb', line 345
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.
384 385 386 |
# File 'lib/haml/util.rb', line 384
def ruby1_8?
Haml::Util::RUBY_VERSION[0] == 1 && Haml::Util::RUBY_VERSION[1] < 9
end
|
#ruby1_8_6? ⇒ Boolean
Whether or not this is running under Ruby 1.8.6 or lower. Note that lower versions are not officially supported.
392 393 394 |
# File 'lib/haml/util.rb', line 392
def ruby1_8_6?
ruby1_8? && Haml::Util::RUBY_VERSION[2] < 7
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
|
#set_eql?(set1, set2) ⇒ Boolean
Tests the hash-equality of two sets in a cross-version manner. Aggravatingly, this is order-dependent in Ruby 1.8.6.
511 512 513 514 |
# File 'lib/haml/util.rb', line 511
def set_eql?(set1, set2)
return set1.eql?(set2) unless ruby1_8_6?
set1.to_a.uniq.sort_by {|e| e.hash}.eql?(set2.to_a.uniq.sort_by {|e| e.hash})
end
|
#set_hash(set) ⇒ Fixnum
Returns the hash code for a set in a cross-version manner. Aggravatingly, this is order-dependent in Ruby 1.8.6.
500 501 502 503 |
# File 'lib/haml/util.rb', line 500
def set_hash(set)
return set.hash unless ruby1_8_6?
set.map {|e| e.hash}.uniq.sort.hash
end
|
#silence_haml_warnings { ... }
Silences all Haml warnings within a block.
239 240 241 242 243 244 245 |
# File 'lib/haml/util.rb', line 239
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.
228 229 230 231 232 233 |
# File 'lib/haml/util.rb', line 228
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.
585 586 587 |
# File 'lib/haml/util.rb', line 585
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
|