How to let a user render a partial?

how about doing something like this logic

scan your content looking for "{" store everything until your next "}" into a string variable # now string = "test foo:foo bar bar:bar foo" split your string by spaces into an array # now array = ["test", "foo:foo", "bar", "bar:bar", "foo"]

loop through your array new_array = index = 0 array.each do |a|     if a does not contain ":"         index = index + 1         partial = a         args = {}         new_array[index] = [partial, args]     else         args = new_array[index][2] # should be a hash         name, value = a.split(/:/)         args[name.to_sym] = value # add new args to hash         new_array[index][2] = args # store hash back into the array     end end

# now new_array = [["foo", {foo => "foo"}], ["bar", {bar => "bar"}], ["foo", {}]] loop through this and render partials new_array.each do |a|     partial = a[1]     arguments = a[2]     output << render(:partial => "drops/#{partial}", :locals => arguments) end

i am sure there are errors and bugs but i think the basic logic should work. it will probably turn out to be fairly clean and readable if refactored into a few methods.

Greedy things like .* are almost always dangerous as they make you consume the entire string. typically you'd want to scan or scan_until the first occurence of something

the following modification to the previous solution does that:

def dropify(content)   s = StringScanner.new(content)   output = ""   previous_end = 0   while s.scan_until(/\{/)     output << content[previous_end, s.pointer - previous_end - 1]     partial = s.scan(/\w+/)     s.skip /\s+/     arguments = {}     while label= s.scan(/(\w+):"/)       name=s[1]       value = s.scan /[^"]+/       arguments[name.to_sym] = value       s.skip /"\s+/     end     s.skip_until /\}/     previous_end = s.pointer     puts arguments.inspect     end end

Having scanned \w+:" (ie a label and the opening quote mark) we consume all non " characters and says those are the arguments. then we skip over the closing " and any whitespace

dropify('{test_partial foo:"bar foo" bar:"foo bar"}')

outputs

{:foo=>"bar foo", :bar=>"foo bar"}

Fred