module CurlyBracketParser

CurlyBracketParser

Parse variables with curly brackets within templates/strings or files

Use filters for special cases

Constants

VALID_DEFAULT_FILTERS
VARIABLE_DECODER_REGEX

{{variable_name|optional_filter}}

VARIABLE_REGEX
VERSION

Public Class Methods

any_variable_included?(string) click to toggle source

Check if any variable is included in the given string

@param [String] string name of variable to check for @return [Boolean] true if any variable is included in the given string, otherwise false

# File lib/curly_bracket_parser.rb, line 293
def self.any_variable_included?(string)
  string.match(VARIABLE_REGEX) != nil
end
decode_variable(variable) click to toggle source

Return a hash containing separated name and filter of a variable

@example

'{{var_name|filter_name}}' => { name: 'var_name', filter: 'filter_name' }

@param [String] variable @return [Hash<String => String>] name, filter

# File lib/curly_bracket_parser.rb, line 258
def self.decode_variable(variable)
  decoded_variables(variable).first
end
decoded_variables(string) click to toggle source

Scans the given url for variables with pattern '{{var|optional_filter}}'

@example

'The variable {{my_var|my_filter}} is inside this string' => [{ name: "my_var", filter: "my_filter"}]

@param [String] string to scan @return [Array<Hash<Symbol => String>>] array of variable names and its filters

# File lib/curly_bracket_parser.rb, line 271
def self.decoded_variables(string)
  var_name_index = 0
  var_filter_index = 1
  string.scan(VARIABLE_DECODER_REGEX).map { |e| { name: "#{e[var_name_index].strip}", filter: e[var_filter_index].strip != '' ? e[var_filter_index].strip : nil } }.flatten
end
includes_one_variable_of(variable_names, string) click to toggle source

Check if one of the given variable names is included in the given string

@param [Array<String>] variable_names @param [String] string name of variable to check for @return [Boolean] true if one given variable name is included in given the string, otherwise false

# File lib/curly_bracket_parser.rb, line 304
def self.includes_one_variable_of(variable_names, string)
  decoded_variables(string).each do |dvar|
    return true if variable_names.include?(dvar[:name])
  end
  false
end
parse(string, variables, unresolved_vars: :raise, replace_pattern: " click to toggle source

Parse given string and replace the included variables by the given variables

@param [String] string to parse @param [Hash<Symbol => String>] variables <key: 'value'> @param [Symbol] unresolved_vars :raise, :keep, :replace => define how to act when unresolved variables within the string are found. @param [String] replace_pattern pattern used when param unresolved_vars is set to :replace. You can include the var name \1 and filter \2. Empty string to remove unresolved variables. @return [String, UnresolvedVariablesError] parsed string

# File lib/curly_bracket_parser.rb, line 37
def self.parse(string, variables, unresolved_vars: :raise, replace_pattern: "##\\1##")
  variables ||= {}
  result_string = string.clone
  if CurlyBracketParser.any_variable_included? string
    loop do
      variables(string).each do |string_var|
        dec = decode_variable(string_var)
        name = dec[:name]
        filter = dec[:filter]
        if variables[name.to_sym]
          value = if filter
                    process_filter(filter, variables[name.to_sym])
                  else
                    variables[name.to_sym]
                  end
          result_string.gsub!(string_var, value)
        elsif registered_default_var?(name.to_s)
          value = process_default_var(name)
          result_string.gsub!(string_var, value)
        end
      end
      # break if no more given variable is available
      break unless any_variable_included?(string) && includes_one_variable_of(variables, string)
    end
    case unresolved_vars
    when :raise
      if any_variable_included? result_string
        raise UnresolvedVariablesError, "There are unresolved variables in the given string: #{variables(result_string)}"
      end
    when :replace
      result_string.gsub!(VARIABLE_DECODER_REGEX, replace_pattern)
    end
  end
  result_string
end
parse_file(path, variables, unresolved_vars: :raise, replace_pattern: " click to toggle source

Parse the content of the file of the given path with parse and return it. The original file keeps unmodified.

@param [String] string to parse @param [Hash<Symbol => String>] variables <key: 'value'> @param [Symbol] unresolved_vars :raise, :keep, :replace => define how to act when unresolved variables within the string are found. @param [String] replace_pattern pattern used when param unresolved_vars is set to :replace. You can include the var name \1 and filter \1. Empty string to remove unresolved variables. @return [String, UnresolvedVariablesError] parsed string

# File lib/curly_bracket_parser.rb, line 83
def self.parse_file(path, variables, unresolved_vars: :raise, replace_pattern: "##\\1##")
  file_content = File.read path
  parse(file_content, variables, unresolved_vars: unresolved_vars, replace_pattern: replace_pattern)
end
parse_file!(path, variables, unresolved_vars: :raise, replace_pattern: " click to toggle source

Parse the content of the file of the given path with parse and return it. The original file will be overwritten by the parsed content.

@param [String] string to parse @param [Hash<Symbol => String>] variables <key: 'value'> @param [Symbol] unresolved_vars :raise, :keep, :replace => define how to act when unresolved variables within the string are found. @param [String] replace_pattern pattern used when param unresolved_vars is set to :replace. You can include the var name \1 and filter \1. Empty string to remove unresolved variables. @return [String, UnresolvedVariablesError] parsed string

# File lib/curly_bracket_parser.rb, line 96
def self.parse_file!(path, variables, unresolved_vars: :raise, replace_pattern: "##\\1##")
  parsed_file = parse_file path, variables, unresolved_vars: unresolved_vars, replace_pattern: replace_pattern
  File.write path, parsed_file
  parsed_file
end
process_default_var(name) click to toggle source

Return the given default variable by returning the result of its block/proc

@param [String] name of the variable to return @return [String] value of the variable

# File lib/curly_bracket_parser.rb, line 186
def self.process_default_var(name)
  @@registered_default_vars ||= {}
  name = name.to_s
  if @@registered_default_vars[name]
    @@registered_default_vars[name].call()
  else
    message = "Invalid default variable '#{name}'. Valid registered default variables are: #{self.registered_default_vars.keys.join(' ')}"
    raise InvalidVariableError, message
  end
end
process_filter(filter, value) click to toggle source

Process the given value with the given filter

@param [String] filter name of the filter, also used then in your strings, e.g. {{var_name|my_filter_name}} @param [String] value string to apply the specified filter on @return [String] converted string with applied filter

# File lib/curly_bracket_parser.rb, line 127
def self.process_filter(filter, value)
  @@registered_filters ||= {}
  filter = filter.to_s
  if @@registered_filters[filter]
    @@registered_filters[filter].call(value)
  elsif VALID_DEFAULT_FILTERS.include?(filter) && LuckyCase.valid_case_type?(filter)
    LuckyCase.convert_case(value, filter)
  else
    message = "Invalid filter '#{filter}'. Valid filters are: #{self.valid_filters.join(' ')}"
    raise InvalidFilterError, message
  end
end
register_default_var(name, &block) click to toggle source

Register a default variable to be replaced automatically by the given block value in future If the variable exists already, it will raise an VariableAlreadyRegisteredError

@param [String] name of the default var @param [Proc] block @raise [VariableAlreadyRegisteredError] if variable is already registered @return [Proc] given block

# File lib/curly_bracket_parser.rb, line 170
def self.register_default_var(name, &block)
  @@registered_default_vars ||= {}
  name = name.to_s
  if registered_default_var?(name)
    raise VariableAlreadyRegisteredError, "The given variable name '#{name}' is already registered. If you want to override that variable explicitly, call #register_default_var! instead!"
  else
    @@registered_default_vars[name] = block
  end
end
register_default_var!(name, &block) click to toggle source

Register a default variable to be replaced automatically by the given block value in future If the variable exists already, it will be overwritten

@param [String] name of the default var @param [Proc] block @raise [VariableAlreadyRegisteredError] if variable is already registered @return [Proc] given block

# File lib/curly_bracket_parser.rb, line 206
def self.register_default_var!(name, &block)
  @@registered_default_vars ||= {}
  name = name.to_s
  @@registered_default_vars[name] = block
end
register_filter(filter, &block) click to toggle source

Register your custom filter to the filter list

@param [String] filter name of the filter, also used then in your strings, e.g. {{var_name|my_filter_name}} @param [Lambda] function of the filter to run the variable against @raise [FilterAlreadyRegisteredError] if filter does already exist @return [Proc] given block

# File lib/curly_bracket_parser.rb, line 110
def self.register_filter(filter, &block)
  @@registered_filters ||= {}
  filter = filter.to_s
  if valid_filter?(filter)
    raise FilterAlreadyRegisteredError, "The given filter name '#{filter}' is already registered"
  else
    @@registered_filters[filter] = block
  end
end
registered_default_var?(name) click to toggle source

Check if the given variable is a registered default variable

@param [String] name of the variable @return [Boolean] true if variable is registered, otherwise false

# File lib/curly_bracket_parser.rb, line 245
def self.registered_default_var?(name)
  self.registered_default_vars.include? name
end
registered_default_vars() click to toggle source

Return an array of registered default variables

@return [Array<String>]

# File lib/curly_bracket_parser.rb, line 234
def self.registered_default_vars
  @@registered_default_vars ||= {}
  @@registered_default_vars.keys.map(&:to_s)
end
unregister_default_var(name) click to toggle source

Unregister / remove an existing default variable

@param [String] name of the variable @return [Boolean] true if variable existed and was unregistered, false if it didn't exist

# File lib/curly_bracket_parser.rb, line 218
def self.unregister_default_var(name)
  @@registered_default_vars ||= {}
  name = name.to_s
  if @@registered_default_vars[name]
    @@registered_default_vars.delete(name)
    true
  else
    false
  end
end
valid_filter?(name) click to toggle source

Check if a given filter is valid

@param [String] name @return [Boolean] true if filter exists, otherwise false

# File lib/curly_bracket_parser.rb, line 157
def self.valid_filter?(name)
  self.valid_filters.include? name
end
valid_filters() click to toggle source

Retrieve Array with valid filters

@return [Array<String>] of valid filters

# File lib/curly_bracket_parser.rb, line 145
def self.valid_filters
  all_filters = VALID_DEFAULT_FILTERS
  @@registered_filters ||= {}
  all_filters + @@registered_filters.keys.map(&:to_s)
end
variables(string) click to toggle source

Scans the given url for variables with pattern '{{var|optional_filter}}'

@param [String] string to scan @return [Array<String>] array of variable names and its filters

# File lib/curly_bracket_parser.rb, line 283
def self.variables(string)
  string.scan(VARIABLE_REGEX).flatten
end