module Haml::Util

def av_template_class(name)

Parameters:
  • name (#to_s) -- The name of the class to get.
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

def balance(scanner, start, finish, count = 0)

Returns:
  • ((String, String)) - The string matched within the balanced pair

Parameters:
  • count (Fixnum) -- The number of opening characters matched
  • finish (Character) -- The character closing the balanced pair.
  • start (Character) -- The character opening the balanced pair.
  • scanner (StringScanner) -- The string scanner to move
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

def caller_info(entry = caller[1])

Returns:
  • ([String, Fixnum, (String, nil)]) - An array containing the filename, line, and method name of the caller.

Parameters:
  • entry (String) -- An entry in the `#caller` list, or a similarly formatted string
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

def check_encoding(str)

def check_encoding(str)
  str.gsub(/\A\xEF\xBB\xBF/, '') # Get rid of the UTF-8 BOM
end

def check_encoding(str)

def check_encoding(str)
  if 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
d #{encoding.name} character #{e.error_char.dump}
    end
  end
  return str
end

def check_haml_encoding(str, &block)

Raises:
  • (ArgumentError) - if the document declares an unknown encoding

Returns:
  • (String) - The original string encoded properly

Other tags:
    Yieldparam: msg - The error message to be raised

Other tags:
    Yield: - A block in which an encoding error can be raised.

Parameters:
  • str (String) -- The Haml template of which to check the encoding
def check_haml_encoding(str, &block)
  check_encoding(str, &block)
end

def check_haml_encoding(str, &block)

def check_haml_encoding(str, &block)
  str = str.dup if str.frozen?
  bom, encoding = parse_haml_magic_comment(str)
  if encoding; str.force_encoding(encoding)
  elsif bom; str.force_encoding("UTF-8")
  end
  return check_encoding(str, &block)
end

def contains_interpolation?(str)

def contains_interpolation?(str)
  str.include?('#{')
end

def def_static_method(klass, name, args, *vars)

Parameters:
  • vars (Array) -- The names of the static boolean variables
  • args (Array) -- The names of the arguments to the defined methods
  • name (#to_s) -- The (base) name of the static method
  • klass (Module) -- The class on which to define the static method

Overloads:
  • def_static_method(klass, name, args, *vars, erb)
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
OD
  end
end

def handle_interpolation(str)

Returns:
  • (String) - The text remaining in the scanner after all `#{`s have been processed

Other tags:
    Yieldparam: scan - The scanner scanning through the string
def handle_interpolation(str)
  scan = StringScanner.new(str)
  yield scan while scan.scan(/(.*?)(\\*)\#\{/)
  scan.rest
end

def html_safe(text)

Returns:
  • (String, nil) - `text`, marked as HTML-safe

Parameters:
  • text (String, nil) --
def html_safe(text)
  return unless text
  text.html_safe
end

def human_indentation(indentation)

Returns:
  • (String) - The name of the indentation (e.g. `"12 spaces"`, `"1 tab"`)

Parameters:
  • indentation (String) -- The string used for indentation
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

def inspect_obj(obj)

def inspect_obj(obj)
  return obj.inspect
end

def inspect_obj(obj)

Returns:
  • (String) -

Parameters:
  • obj (Object) --
def inspect_obj(obj)
  return ':' + inspect_obj(obj.to_s) if obj.is_a?(Symbol)
  return obj.inspect unless obj.is_a?(String)
  '"' + obj.gsub(/[\x00-\x7F]+/) {|s| s.inspect[1...-1]} + '"'
end

def parse_haml_magic_comment(str)

Returns:
  • ((Boolean, String or nil)) -
def parse_haml_magic_comment(str)
  scanner = StringScanner.new(str.dup.force_encoding("BINARY"))
  bom = scanner.scan(/\xEF\xBB\xBF/n)
  return bom unless scanner.scan(/-\s*#\s*/n)
  if coding = try_parse_haml_emacs_magic_comment(scanner)
    return bom, coding
  end
  return bom unless scanner.scan(/.*?coding[=:]\s*([\w-]+)/in)
  return bom, scanner[1]
end

def powerset(arr)

Returns:
  • (Set) - The subsets of `arr`

Parameters:
  • arr (Enumerable) --
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

def rails_xss_safe?; true; end

def rails_xss_safe?; true; end

def rails_xss_safe?

Returns:
  • (Boolean) -
def rails_xss_safe?
  false
end

def silence_warnings

Other tags:
    Yield: - A block in which no output will be printed to STDERR
def silence_warnings
  the_real_stderr, $stderr = $stderr, StringIO.new
  yield
ensure
  $stderr = the_real_stderr
end

def static_method_name(name, *vars)

Returns:
  • (String) - The real name of the static method

Parameters:
  • vars (Array) -- The static variable assignment
  • name (String) -- The base name of the static method
def static_method_name(name, *vars)
  :"#{name}_#{vars.map {|v| !!v}.join('_')}"
end

def try_parse_haml_emacs_magic_comment(scanner)

def try_parse_haml_emacs_magic_comment(scanner)
  pos = scanner.pos
  return unless scanner.scan(/.*?-\*-\s*/n)
  # From Ruby's parse.y
  return unless scanner.scan(/([^\s'":;]+)\s*:\s*("(?:\\.|[^"])*"|[^"\s;]+?)[\s;]*-\*-/n)
  name, val = scanner[1], scanner[2]
  return unless name =~ /(en)?coding/in
  val = $1 if val =~ /^"(.*)"$/n
  return val
ensure
  scanner.pos = pos
end

def unescape_interpolation(str, escape_html = nil)

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