class Florrick::Builder

Constants

VALID_EXPORT_TYPES

Attributes

objects[R]
original_string[R]

Public Class Methods

new(string, objects = {}) click to toggle source
# File lib/florrick/builder.rb, line 8
def initialize(string, objects = {})
  @original_string = string
  @objects = objects
end

Public Instance Methods

output() click to toggle source
# File lib/florrick/builder.rb, line 13
def output
  string = @original_string.dup
  string.gsub(/(\{\{\s*([\w+\.]+)(?>\ ?\|\ ?([\w\-\+\ \!\?\[\]\(\)]+))?\s*\}\})/) do
    original_string = $1
    fallback_string = $3 ? $3.strip : nil
    parts = $2.downcase.split('.')
    final_string = nil
    previous_object = @objects[parts.shift.to_sym]

    if previous_object.nil?
      final_string = fallback_string || original_string
    end

    until final_string
      # get the latest part
      if var = parts.shift
        # if the previous object is suitable for string interpolation, we can
        # pass the var to it and get out a string or an integer.
        if previous_object.respond_to?(:string_interpolation_value_for)
          if previous_object.class.string_interpolation_for?(var)
            # we can do this easily
            previous_object = previous_object.string_interpolation_value_for(var)
            # if the previous object was nil, just set to the fallback string or empty
            if previous_object.nil? || (previous_object.is_a?(Array) && previous_object.empty?)
              final_string = fallback_string || ''
            end
          elsif previous_object.class.string_interpolation_relationship_for?(var)
            # maybe we can do this on another object
            previous_object = previous_object.send(var)
          else
            # can't do this :(
            final_string = fallback_string || original_string
          end
        elsif VALID_EXPORT_TYPES.any? { |t| previous_object.is_a?(t)}
          previous_object = Florrick::Formatter.convert(var, previous_object)
        else
          # does not respond to string_interpolation_value_for and isn't a valid object,
          # we can't do anything here just return the passed value.
          final_string = fallback_string || original_string
        end
      else
        # we're at the end now, if we can return the previous object, lets do it otherwise
        # we'll just return the string as we can't do anything.
        if VALID_EXPORT_TYPES.any? { |t| previous_object.is_a?(t)}
          final_string = previous_object
        else
          final_string = fallback_string || original_string
        end
      end
    end

    case final_string
    when Array
      final_string.join(", ")
    else
      final_string.to_s
    end
  end
end