Skip to content

Instantly share code, notes, and snippets.

@ElManouche
Last active April 26, 2017 17:49
Show Gist options
  • Save ElManouche/038ae1e756fc9293bec3b040e9f38f57 to your computer and use it in GitHub Desktop.
Save ElManouche/038ae1e756fc9293bec3b040e9f38f57 to your computer and use it in GitHub Desktop.
SiRuMeT - Simple Ruby Merge Tags Parser - created by ElManouche - https://repl.it/HWwM/25
# SiRuMeT - Simple Ruby Merge Tags Parser
## Code
def parse_merge_tags(text, params)
pattern = {
placeholder: /(\*\|(?:MC:)?([A-Za-z0-9_]+)\|\*)/,
condition: %r{
(
\*\|IF:
([A-Za-z0-9_]+) # match[1] 2nd Capturing Group - merge_tag
(?:
[\s]*
(=|!=|>=|<=|<|>) # match[2] 3rd Capturing Group - operation
[\s]*
([^\*]+?) # match[3] 4th Capturing Group - value
)?
\|\*
(?:
(?:
([^\*]*) # match[4] 5th Capturing Group - consequent
\*\|ELSE:\|\*
([^\*]*) # match[5] 6th Capturing Group - alternative
)
|
([^\*]*) # match[6] 7th Capturing Group - single_consequent
)
\*\|END:IF\|\*
) # match[0] 1st Capturing Group - capture_text
}x
}
# Scan for placeholder tags
text.scan(pattern[:placeholder]).each do |match|
value = params[match[1]]
text = if value.nil?
text.gsub(match[0], '')
else
text.gsub(match[0], value)
end
end
# Scan for conditions
text.scan(pattern[:condition]).each do |match|
text = perform_match text, match, params
end
text
end
def perform_match(text, match, params)
value = params[match[1]]
match[2] = '==' if match[2] == '='
condition_respected =
if match[2].nil?
# Condition has no operator
# Test only if value exists
!value.nil?
elsif ['>=', '<=', '<', '>'].include?(match[2])
# Numerical comparaison
!value.nil? && value.to_i.send(match[2], match[3].to_i)
else
# String comparaison
!value.nil? && value.to_s.send(match[2], match[3].to_s)
end
has_else_statement = match[6].nil?
# Replace the occurrences in the text
text = replace_text_occurrences(text, has_else_statement, condition_respected, match)
# Remove multiple line breaks
text.gsub(/\n\s*\n\s*\n/, "\n\n").strip
end
# Replace the occurrences in the text
def replace_text_occurrences(text, has_else_statement, condition_respected, match)
if has_else_statement && condition_respected
text.gsub(match[0], match[4])
elsif has_else_statement && !condition_respected
text.gsub(match[0], match[5])
elsif !has_else_statement && condition_respected
text.gsub(match[0], match[6])
else
text.gsub(match[0], '')
end
end
## Example
message = <<-eos
***|MC:SUBJECT|***
Hello *|IF:FNAME|*
*|FNAME|*,
*|ELSE:|*
Friend,
*|END:IF|*
*|IF:MC_LANGUAGE=es|*
Spanish content here.
*|ELSE:|*
Display English content for everyone else.
*|END:IF|*
*|IF:TRANSACTIONS >= 10|*
Enjoy this 20% off coupon! *|COUPON20|*
*|ELSE:|*
Enjoy this 10% off coupon! *|COUPON10|*
*|END:IF|*
eos
params = {
'SUBJECT' => 'SiRuMeT',
'FNAME' => 'John Doe',
'MC_LANGUAGE' => 'es',
'TRANSACTIONS' => 15
}
puts parse_merge_tags(message, params)
## Result
# => "**SiRuMeT**\n\nHello \n John Doe,\n\nSpanish content here.\n\n Enjoy this 20% off coupon!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment