Created
December 3, 2013 06:12
-
-
Save nambrot/7764646 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'json' | |
# Parse CMD Args | |
template_file = ARGV.first | |
data_json = ARGV[1] | |
output_file = ARGV.last | |
# Read Files | |
data = JSON.parse open(data_json).read() | |
template = open(template_file).read() | |
# Provide dot syntax for hashes | |
def dot_access(hash, route) | |
route.split('.').reduce(hash){|hash, key| hash[key]} | |
end | |
# returns the MatchData Object for the closing tag of the first directive | |
def find_closing_tag(template) | |
matches = template.to_enum(:scan, /<\* ([A-Z]+)(.*?|.?) \*>/m).map{Regexp.last_match} | |
# iterate through the matches and look out for enclosed directives | |
count = 0 | |
for match in matches | |
count += 1 if match[1] == matches.first[1] | |
count -= 1 if match[1] == "END" + matches.first[1] | |
return match if count == 0 | |
end | |
end | |
# recursive parsing | |
def parse_template(template, context) | |
return_string = "" | |
# iterate through the string and find template directives | |
while match = template.match(/<\* (.*?) \*>/m) | |
# match behavior on tag name | |
case match[1] | |
when /EACH ([a-z\d\.]*) ([a-z\d]*)/ | |
# add non-tag template part | |
return_string += match.pre_match | |
# find the corresponding closing tag | |
closing_tag = find_closing_tag(template) | |
# loop through the appropriate object and parse recursively | |
for obj in dot_access(context, $1) | |
new_context = context.dup | |
new_context[$2] = obj | |
return_string += parse_template(template.slice(match.end(0)..find_closing_tag(template).begin(0)-1), new_context) | |
end | |
# remove directive part of template | |
template.slice!(0..closing_tag.end(0)-1) | |
else | |
# simple value insert | |
return_string += match.pre_match | |
return_string += dot_access(context, match[1]) | |
template = match.post_match | |
end | |
end | |
# append the rest of the template | |
return_string += template | |
return return_string | |
end | |
# write to file | |
File.open(output_file, 'w') {|f| f.write(parse_template(template, data)) } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment