Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to find nested opening and closing tags

Tags:

ruby

I am making a basic discussion board using ROR. When a user posts a response to a message, the input textarea is prepopulated with the message in quotes using a tag: [QUOTE]. As such the format is:

[QUOTE]quoted message goes here[/QUOTE]

Currently, I have a simple solution that replaces [QUOTE] and [/QUOTE] with HTML using message.sub('[QUOTE]', 'html goes here') as long as [QUOTE] or [/QUOTE] still exist. When I go to respond to a quoted message, I convert the HTML back into the [QUOTE] tag to ensure that the prepopulated input textarea doesn't have HTML in it. As such, a quote of a quote, will look like:

[QUOTE][QUOTE]quoted message here[/QUOTE][/QUOTE]

Here is the problem. If I run my current method again, I will get duplicated HTML fields like:

<div class='test'><div class='test'>quoted message goes here</div></div>

Instead, I want to be able to have a solution that looks like:

<div class='test1'><div class='test2'>quoted message goes here</div></div>

And so on... Any suggestions on the best way to loop this?

like image 673
Marc Avatar asked Dec 04 '25 02:12

Marc


1 Answers

If you want to do depth tracking you'll have to use the block method for gsub:

text = "[QUOTE][QUOTE]quoted message here[/QUOTE][/QUOTE]"

quote_level = 0

new_text = text.gsub(/\[\/?QUOTE\]/) do |m|
  case (m)
  when '[QUOTE]'
    quote_level += 1
    "<div class='test#{quote_level}'>"
  when '[/QUOTE]'
    quote_level -= 1
    "</div>"
  end
end

puts new_text.inspect
# => "<div class='test1'><div class='test2'>quoted message here</div></div>"

You could make this more robust when handling invalid nesting pairs, but for well-formatted tags this should work.

like image 95
tadman Avatar answered Dec 05 '25 17:12

tadman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!