On 9 Oct 2008, at 15:52, David Trasbo wrote:

>
> Frederick Cheung wrote:
>
>>> In this case the partial is longer than the {some_partial} and  
>>> some of
>>> the second instance of the partial disappears. How can I force  
>>> Ruby to
>>> replace the characters between to positions with a longer string?
>>
>> You could fiddle with insert or something like that. There is another
>> way of doing it:
>> Say you've determine the two sections to replace are between  
>> positions
>> 20 and 40 and then between 100 and 120
>> you would do
>>
>> result = ""
>> result << original_string[0, 20]
>> result << render of first section
>> result << original_string[40, 60]
>> result << render of last section
>> result << original_string[120, original_string.length - 120
>
> That's seems a little complicated (and I don't see the flexibility of
> it, either) but now I'm using the String#insert and at the end I do a
> String#gsub to remove the {some_partial foo:bar}'s.
>

It avoids the need to maintain the drop array (and also means that you  
don't need a gsub that as is i believe will remove the wrong content  
if there are more than one partial (because the * is greedy)

you could have something like

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

which is marginally simpler (the above could contain off by 1 errors  
in the various offsets).

Fred

> So my final method looks like this:
>
> ==========
> def dropify(content)
>  s = StringScanner.new(content)
>  drops = Array.new
>  while s.scan_until(/\{/)
>    drop = {}
>    drop[:from] = s.pointer - 1
>    drop[:arguments] = {}
>    drop[:partial] = s.scan(/\w+/)
>    s.skip /\s+/
>    while argument = s.scan(/\w+:\w+/)
>      name, value = argument.split(/:/)
>      drop[:arguments][name.to_sym] = value
>      s.skip /\s+/
>    end
>    s.skip_until /\}/
>    drops << drop
>  end
>  drops.reverse!
>  drops.each do |drop|
>    content.insert(drop[:from], render(:partial =>
> "drops/#{drop[:partial]}", :locals => drop[:arguments]))
>  end
>  content.gsub!(/\{\w+.*\}/, "")
>  content
> end
> ==========
>
> Thanks for your help! I hope some of you can use this method as well.
> -- 
> Posted via http://www.ruby-forum.com/.
>
> >


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Talk" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to