Module: Haml::Util

### Home Classes Methods

### In Files

- lib/haml/template.rb
- lib/haml/util.rb

### Namespace

- CLASS Haml::Util::StaticConditionalContext

### Methods

- #av_template_class
- #balance
- #caller_info
- #check_encoding
- #check_haml_encoding
- #contains_interpolation?
- #def_static_method
- #handle_interpolation
- #html_safe
- #human_indentation
- #inspect_obj
- #powerset
- #rails_xss_safe?
- #silence_warnings
- #static_method_name
- #unescape_interpolation

### Class/Module Index

Quicksearch

- Haml
- Haml::Buffer
- Haml::Compiler
- Haml::Engine
- Haml::Error
- Haml::ErubisTemplateHandler
- Haml::Exec
- Haml::Exec::Generic
- Haml::Exec::Haml
- Haml::Filters
- Haml::Filters::Base
- Haml::Filters::Cdata
- Haml::Filters::Css
- Haml::Filters::Erb
- Haml::Filters::Escaped
- Haml::Filters::Javascript
- Haml::Filters::Plain
- Haml::Filters::PrecompiledTiltFilter
- Haml::Filters::Preserve
- Haml::Filters::Ruby
- Haml::Filters::SassRailsTemplate
- Haml::Filters::ScssRailsTemplate
- Haml::Filters::TiltFilter
- Haml::Helpers
- Haml::Helpers::ActionViewExtensions
- Haml::Helpers::ErrorReturn
- Haml::Helpers::XssMods
- Haml::Options
- Haml::Parser
- Haml::Parser::Line
- Haml::Parser::ParseNode
- Haml::Plugin
- Haml::Railtie
- Haml::SafeErubisTemplate
- Haml::SyntaxError
- Haml::Template
- Haml::Util
- Haml::Util::StaticConditionalContext
- ActionView
- ActionView::Base
- ActionView::Helpers
- ActionView::Helpers::CaptureHelper
- ActionView::Helpers::FormHelper
- ActionView::Helpers::FormTagHelper
- ActionView::Helpers::HamlSupport
- ActionView::Helpers::InstanceTag
- ActionView::Helpers::TagHelper
- ActionView::Helpers::Tags
- ActionView::Helpers::Tags::TextArea
- ActionView::Helpers::TextHelper
- Object

No matching classes.

# Haml::Util

A module containing various useful functions.

### Public Instance Methods

av_template_class(name) click to toggle source

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`.

@param name [to_s] The name of the class to get.

    For example, `:Error` will return `ActionView::TemplateError`
    or `ActionView::Template::Error`.

    # 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) click to toggle source

Moves a scanner through a balanced pair of characters. For example:

    Foo (Bar (Baz bang) bop) (Bang (bop bip))
    ^                       ^
    from                    to

@param scanner [StringScanner] The string scanner to move @param start [Character] The character opening the balanced pair.

    A `Fixnum` in 1.8, a `String` in 1.9

@param finish [Character] The character closing the balanced pair.

    A `Fixnum` in 1.8, a `String` in 1.9

@param count [Fixnum] The number of opening characters matched

    before calling this method

@return [(String, String)] The string matched within the balanced pair

    and the rest of the string.
    `["Foo (Bar (Baz bang) bop)", " (Bang (bop bip))"]` in the example above.

    # 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]) click to toggle source

Returns information about the caller of the previous method.

@param entry [String] An entry in the `caller` list, or a similarly formatted string @return [[String, Fixnum, (String, nil)]] An array containing the filename, line, and method name of the caller.

    The method name may be nil

    # 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) click to toggle source

    # 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, &block) click to toggle source

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`.

@param str [String] The Haml template of which to check the encoding @yield [msg] A block in which an encoding error can be raised.

    Only yields if there is an encoding error

@yieldparam msg [String] The error message to be raised @return [String] The original string encoded properly @raise [ArgumentError] if the document declares an unknown encoding

    # File lib/haml/util.rb, line 154
    def check_haml_encoding(str, &block)
      check_encoding(str, &block)
    end

contains_interpolation?(str) click to toggle source

    # File lib/haml/util.rb, line 324
    def contains_interpolation?(str)
      str.include?('#{')
    end

def_static_method(klass, name, args, *vars) click to toggle source

This is used for methods in {Haml::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.

@overload def_static_method(klass, name, args, *vars, erb) @param klass [Module] The class on which to define the static method @param name [to_s] The (base) name of the static method @param args [Array<Symbol>] The names of the arguments to the defined methods

    (**not** to the ERB template)

@param vars [Array<Symbol>] The names of the static boolean variables

    to be made available to the ERB template

    # 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(          def #{static_method_name(name, *vars.map {|v| set.include?(v)})}(#{args.join(', ')})            #{method_content}          end, info[0], info[1])
      end
    end

handle_interpolation(str) click to toggle source

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`), and the text prior to that as the first (`scan`).

@yieldparam scan [StringScanner] The scanner scanning through the string @return [String] The text remaining in the scanner after all `#{`s have been processed

    # 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) click to toggle source

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`.

@param text [String, nil] @return [String, nil] `text`, marked as HTML-safe

    # File lib/haml/util.rb, line 87
    def html_safe(text)
      return unless text
      text.html_safe
    end

human_indentation(indentation) click to toggle source

Formats a string for use in error messages about indentation.

@param indentation [String] The string used for indentation @return [String] The name of the indentation (e.g. `“12 spaces”`, `“1 tab”`)

    # 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) click to toggle source

    # File lib/haml/util.rb, line 171
    def inspect_obj(obj)
      return obj.inspect
    end

powerset(arr) click to toggle source

Computes the powerset of the given array. This is the set of all subsets of the array.

@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]]

@param arr [Enumerable] @return [Set<Set>] The subsets of `arr`

    # 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?() click to toggle source

    # File lib/haml/template.rb, line 23
    def rails_xss_safe?; true; end

silence_warnings() click to toggle source

Silence all output to STDERR within a block.

@yield A block in which no output will be printed to STDERR

    # 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) click to toggle source

Computes the name for a method defined via {#def_static_method}.

@param name [String] The base name of the static method @param vars [Array<Boolean>] The static variable assignment @return [String] The real name of the static method

    # 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) click to toggle source

    # 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

[Validate]

Generated with the Darkfish Rdoc Generator 2.